1 #import "JubGtkChatUI.h"
3 struct add_text_params {
10 static gboolean add_text(gpointer data)
13 struct add_text_params *params = data;
15 if (OF_LIKELY(!params->first))
16 gtk_text_buffer_insert_at_cursor(params->buffer, "\n", 1);
18 gtk_text_buffer_get_end_iter(params->buffer, &endIter);
19 gtk_text_buffer_insert_with_tags_by_name(params->buffer, &endIter,
20 [params->name UTF8String], [params->name UTF8StringLength], "bold",
22 gtk_text_buffer_get_end_iter(params->buffer, &endIter);
23 gtk_text_buffer_insert_with_tags_by_name(params->buffer, &endIter,
24 ": ", 2, "bold", NULL);
26 gtk_text_buffer_insert_at_cursor(params->buffer,
27 [params->text UTF8String], [params->text UTF8StringLength]);
29 [params->name release];
30 [params->text release];
31 g_object_unref(params->buffer);
37 struct call_send_block_params {
38 jub_send_block_t block;
42 static gboolean call_send_block(GtkEntry *entry, GdkEventKey *event,
45 struct call_send_block_params *params = data;
46 if (event->keyval != GDK_KEY_Return &&
47 event->keyval != GDK_KEY_KP_Enter) return TRUE;
50 [[OFString alloc] initWithUTF8String: gtk_entry_get_text(entry)];
51 gtk_entry_set_text(entry, "");
53 [params->chat addMessage: text
60 static gboolean call_close_block(GtkWidget *object, gpointer data)
62 jub_close_block_t block = data;
71 volatile BOOL *initialized;
74 static gboolean init(gpointer data)
76 struct init_params *params = data;
78 GtkTextView *chat_view;
81 GtkBuilder *builder = gtk_builder_new();
82 gtk_builder_add_from_file(builder, "data/gtk/chat.ui", NULL);
84 params->object.chat_window = GTK_WIDGET(
85 gtk_builder_get_object(builder, "ChatWindow"));
86 g_signal_connect(params->object.chat_window, "destroy",
87 G_CALLBACK(call_close_block), params->object.closeBlock);
90 chat_view = GTK_TEXT_VIEW(
91 gtk_builder_get_object(builder, "ChatTextView"));
92 params->object.chat_buffer = gtk_text_view_get_buffer(chat_view);
93 gtk_text_buffer_create_tag(params->object.chat_buffer, "bold",
94 "weight", PANGO_WEIGHT_BOLD, NULL);
96 chat_entry = GTK_ENTRY(
97 gtk_builder_get_object(builder, "ChatEntry"));
98 struct call_send_block_params *send_params =
99 [params->object allocMemoryWithSize: sizeof(*send_params)];
100 send_params->block = params->object.sendBlock;
101 send_params->chat = params->object;
102 g_signal_connect(chat_entry, "key_release_event",
103 G_CALLBACK(call_send_block), send_params);
105 gtk_window_set_title(GTK_WINDOW(params->object.chat_window),
106 [params->title UTF8String]);
107 gtk_widget_show(params->object.chat_window);
109 *params->initialized = YES;
111 g_object_unref(builder);
112 [params->title release];
118 @implementation JubGtkChatUI
119 @synthesize chat_window;
120 @synthesize chat_buffer;
121 @synthesize sendBlock;
122 @synthesize closeBlock;
124 - initWithTitle: (OFString*)title
125 closeBlock: (jub_close_block_t)closeBlock_
126 sendBlock: (jub_send_block_t)sendBlock_
128 volatile BOOL initialized = NO;
133 closeBlock = [closeBlock_ copy];
134 sendBlock = [sendBlock_ copy];
137 struct init_params *params = malloc(sizeof(*params));
138 params->initialized = &initialized;
139 params->title = [title retain];
140 params->object = self;
141 g_idle_add(init, params);
147 while (!initialized);
154 gtk_widget_destroy(chat_window);
156 [closeBlock release];
161 - (void)addMessage: (OFString*)text
162 sender: (OFString*)sender;
164 struct add_text_params *params = malloc(sizeof(*params));
165 params->name = [sender retain];
166 params->text = [text retain];
167 params->buffer = g_object_ref(chat_buffer);
168 params->first = bufferEmpty;
169 g_idle_add(add_text, params);
170 if (OF_UNLIKELY(bufferEmpty)) bufferEmpty = NO;