Makefile: cnoor.o should depend on config.h
[cnoor.git] / txtwin.c
blobe1e967c4d9e3edf072328917b06755fae02f3420
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <gtk/gtk.h>
5 #include <gdk/gdkkeysyms.h>
6 #include "txtwin.h"
7 #include "util.h"
9 struct txtwin {
10 /* A GtkTextView */
11 GtkWidget *main;
12 /* A GtkEntry */
13 GtkWidget *bar;
14 GtkAdjustment *adjst;
17 static void on_window_destroy(GtkWidget *widget, gpointer data)
19 gtk_main_quit();
22 enum location {
23 LOC_PAGE,
24 LOC_STEP,
25 LOC_BEG,
26 LOC_END
29 static void update_bar(struct txtwin *tw)
31 int val = gtk_adjustment_get_value(tw->adjst) +
32 gtk_adjustment_get_page_size(tw->adjst);
33 int max = gtk_adjustment_get_upper(tw->adjst);
34 char msg[128];
35 sprintf(msg, "%d%%", val * 100 / max);
36 gtk_entry_set_text(GTK_ENTRY(tw->bar), msg);
39 static void scroll(struct txtwin *tw, enum location loc, int n)
41 int val = gtk_adjustment_get_value(tw->adjst);
42 int max = gtk_adjustment_get_upper(tw->adjst) -
43 gtk_adjustment_get_page_size(tw->adjst);
44 switch(loc) {
45 case LOC_PAGE:
46 val += n * gtk_adjustment_get_page_increment(tw->adjst);
47 break;
48 case LOC_STEP:
49 val += n * gtk_adjustment_get_step_increment(tw->adjst);
50 break;
51 case LOC_BEG:
52 val = 0;
53 break;
54 case LOC_END:
55 val = max;
56 break;
58 if (val > max)
59 val = max;
60 if (val < 0)
61 val = 0;
62 gtk_adjustment_set_value(tw->adjst, val);
63 update_bar(tw);
66 static gboolean on_key_press(GtkWidget *widget, GdkEventKey *event,
67 gpointer data)
69 struct txtwin *tw = data;
70 int mod = event->state & gtk_accelerator_get_default_mod_mask();
71 if (mod == GDK_CONTROL_MASK) {
72 switch(event->keyval) {
73 case GDK_f:
74 scroll(tw, LOC_PAGE, 1);
75 break;
76 case GDK_b:
77 scroll(tw, LOC_PAGE, -1);
78 break;
79 case GDK_l:
80 gtk_widget_queue_draw(tw->main);
81 break;
82 default:
83 break;
85 return 1;
87 switch(event->keyval) {
88 case GDK_j:
89 scroll(tw, LOC_STEP, 1);
90 break;
91 case GDK_k:
92 scroll(tw, LOC_STEP, -1);
93 break;
94 case GDK_G:
95 scroll(tw, LOC_END, 1);
96 break;
97 case GDK_g:
98 scroll(tw, LOC_BEG, 1);
99 break;
100 case GDK_q:
101 gtk_main_quit();
102 break;
103 default:
104 break;
106 return 1;
109 static void on_size_allocate(GtkWidget *w, GtkAllocation *a, gpointer tw)
111 update_bar(tw);
114 struct txtwin *txtwin_alloc()
116 GtkWidget *window;
117 GtkWidget *vbox;
118 struct txtwin *tw = xmalloc(sizeof(struct txtwin));
119 memset(tw, 0, sizeof(*tw));
120 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
121 gtk_window_set_title(GTK_WINDOW(window), "CNOOR");
122 g_signal_connect(G_OBJECT(window), "destroy",
123 G_CALLBACK(on_window_destroy), NULL);
125 vbox = gtk_vbox_new(FALSE, 2);
126 gtk_container_add(GTK_CONTAINER(window), vbox);
128 /* create the textview */
129 tw->main = gtk_text_view_new();
130 gtk_box_pack_start(GTK_BOX(vbox), tw->main, 1, 1, 0);
131 gtk_signal_connect(GTK_OBJECT(tw->main), "key_press_event",
132 GTK_SIGNAL_FUNC(on_key_press), tw);
133 gtk_signal_connect(GTK_OBJECT(window), "size_allocate",
134 GTK_SIGNAL_FUNC(on_size_allocate), tw);
135 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(tw->main),
136 GTK_WRAP_WORD);
137 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(tw->main), FALSE);
139 /* add the adjustment */
140 tw->adjst = GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 100, 1, 9, 10));
141 gtk_widget_set_scroll_adjustments(tw->main, NULL, tw->adjst);
143 /* create the minibuffer */
144 tw->bar = gtk_entry_new();
145 gtk_box_pack_start(GTK_BOX(vbox), tw->bar, 0, 0, 0);
146 gtk_signal_connect(GTK_OBJECT(tw->bar), "key_press_event",
147 GTK_SIGNAL_FUNC(on_key_press), tw);
148 update_bar(tw);
150 gtk_widget_set_size_request(window, 800, 600);
151 gtk_window_set_default_size(GTK_WINDOW(window), 1024, 768);
152 gtk_widget_show_all(window);
153 return tw;
156 void txtwin_free(struct txtwin *tw)
158 free(tw);
161 void txtwin_loop(struct txtwin *tw)
163 gtk_main();
166 void txtwin_gtk_init(int argc, char **argv)
168 gtk_init(&argc, &argv);
171 static GtkTextBuffer *txtwin_buffer(struct txtwin *tw)
173 return gtk_text_view_get_buffer(GTK_TEXT_VIEW(tw->main));
176 void txtwin_append(struct txtwin *tw, char *s, char *tag)
178 GtkTextIter iter;
179 GtkTextBuffer *buf = txtwin_buffer(tw);
180 gtk_text_buffer_get_end_iter(buf, &iter);
181 gtk_text_buffer_insert_with_tags_by_name(buf, &iter, s, strlen(s),
182 tag, NULL);
185 void txtwin_tag(struct txtwin *tw, char *name, char *fg, char *bg, char *font)
187 GtkTextBuffer *buf = txtwin_buffer(tw);
188 gtk_text_buffer_create_tag(buf, name,
189 "foreground", fg,
190 "background", bg,
191 "font", font,
192 NULL);