]> cgit.babelmonkeys.de Git - jubjub.git/blob - src/gui/gtk/JubGtkChatUI.m
Add some simple chat UI
[jubjub.git] / src / gui / gtk / JubGtkChatUI.m
1 #import "JubGtkChatUI.h"
2
3 struct show_chat_params {
4         GtkWidget *window;
5         OFString *title;
6 };
7
8 static gboolean show_chat(gpointer data)
9 {
10         struct show_chat_params *params = data;
11
12         gtk_window_set_title(GTK_WINDOW(params->window),
13             [params->title UTF8String]);
14         gtk_widget_show(params->window);
15
16         g_object_unref(params->window);
17         [params->title release];
18         free(params);
19
20         return FALSE;
21 }
22
23 struct add_text_params {
24         OFString *name;
25         OFString *text;
26         GtkTextBuffer *buffer;
27         BOOL first;
28 };
29
30 static gboolean add_text(gpointer data)
31 {
32         GtkTextIter endIter;
33         struct add_text_params *params = data;
34
35         if (OF_LIKELY(!params->first))
36                 gtk_text_buffer_insert_at_cursor(params->buffer, "\n", 1);
37
38         gtk_text_buffer_get_end_iter(params->buffer, &endIter);
39         gtk_text_buffer_insert_with_tags_by_name(params->buffer, &endIter,
40             [params->name UTF8String], [params->name UTF8StringLength], "bold",
41             NULL);
42         gtk_text_buffer_get_end_iter(params->buffer, &endIter);
43         gtk_text_buffer_insert_with_tags_by_name(params->buffer, &endIter,
44             ": ", 2, "bold", NULL);
45
46         gtk_text_buffer_insert_at_cursor(params->buffer,
47             [params->text UTF8String], [params->text UTF8StringLength]);
48
49         [params->name release];
50         [params->text release];
51         g_object_unref(params->buffer);
52         free(params);
53
54         return FALSE;
55 }
56
57 static gboolean call_send_block(GtkEntry *entry, GdkEventKey *event,
58     gpointer data)
59 {
60         if (event->keyval != GDK_KEY_Return) return TRUE;
61
62         jub_send_block_t block = data;
63         OFString *text =
64             [[OFString alloc] initWithUTF8String: gtk_entry_get_text(entry)];
65         gtk_entry_set_text(entry, "");
66         block(text);
67         [text release];
68
69         return TRUE;
70 }
71
72 static gboolean add_tags(gpointer data) {
73         gtk_text_buffer_create_tag(data, "bold", "weight",
74             PANGO_WEIGHT_BOLD, NULL);
75
76         return FALSE;
77 }
78
79 @implementation JubGtkChatUI
80 - initWithTitle: (OFString*)title
81       sendBlock: (jub_send_block_t)sendBlock_
82 {
83         self = [super init];
84
85         @try {
86                 GtkTextView *chat_view;
87                 GtkEntry *chat_entry;
88                 GtkBuilder *builder = gtk_builder_new();
89
90                 sendBlock = [sendBlock_ copy];
91                 bufferEmpty = YES;
92
93                 gtk_builder_add_from_file(builder, "data/gtk/chat.ui", NULL);
94
95                 chat_window = GTK_WIDGET(
96                     gtk_builder_get_object(builder, "ChatWindow"));
97
98                 chat_view = GTK_TEXT_VIEW(
99                     gtk_builder_get_object(builder, "ChatTextView"));
100
101                 chat_entry = GTK_ENTRY(
102                     gtk_builder_get_object(builder, "ChatEntry"));
103
104                 g_signal_connect(chat_entry, "key_release_event",
105                     G_CALLBACK(call_send_block), sendBlock);
106
107                 chat_buffer = gtk_text_view_get_buffer(chat_view);
108                 g_idle_add(add_tags, chat_buffer);
109
110                 struct show_chat_params *params = malloc(sizeof(*params));
111                 params->window = g_object_ref(chat_window);
112                 params->title = [title retain];
113                 g_idle_add(show_chat, params);
114
115                 g_object_unref(builder);
116         } @catch (id e) {
117                 [self release];
118                 @throw e;
119         }
120
121         return self;
122 }
123
124 - (void)dealloc
125 {
126         gtk_widget_destroy(chat_window);
127         [sendBlock release];
128
129         [super dealloc];
130 }
131
132 - (void)addMessage: (OFString*)text
133             sender: (OFString*)sender;
134 {
135         struct add_text_params *params = malloc(sizeof(*params));
136         params->name = [sender retain];
137         params->text = [text retain];
138         params->buffer = g_object_ref(chat_buffer);
139         params->first = bufferEmpty;
140         g_idle_add(add_text, params);
141         if (OF_UNLIKELY(bufferEmpty)) bufferEmpty = NO;
142 }
143 @end