1 #import "JubGtkChatUI.h"
2 #import "JubGtkHelper.h"
4 struct call_send_block_params {
5 jub_send_block_t block;
9 static gboolean call_send_block(GtkEntry *entry, GdkEventKey *event,
12 struct call_send_block_params *params = data;
13 if (event->keyval != GDK_KEY_Return &&
14 event->keyval != GDK_KEY_KP_Enter) return TRUE;
17 [[OFString alloc] initWithUTF8String: gtk_entry_get_text(entry)];
18 gtk_entry_set_text(entry, "");
20 [params->chat addMessage: text
27 static gboolean call_close_block(GtkWidget *object, gpointer data)
29 jub_close_block_t block = data;
38 volatile BOOL *initialized;
41 static gboolean init(gpointer data)
43 struct init_params *params = data;
45 GtkTextView *chat_view;
48 GtkBuilder *builder = gtk_builder_new();
49 gtk_builder_add_from_file(builder, "data/gtk/chat.ui", NULL);
51 params->object.chat_window = GTK_WIDGET(
52 gtk_builder_get_object(builder, "ChatWindow"));
53 g_signal_connect(params->object.chat_window, "destroy",
54 G_CALLBACK(call_close_block), params->object.closeBlock);
57 chat_view = GTK_TEXT_VIEW(
58 gtk_builder_get_object(builder, "ChatTextView"));
59 params->object.chat_buffer = gtk_text_view_get_buffer(chat_view);
60 gtk_text_buffer_create_tag(params->object.chat_buffer, "bold",
61 "weight", PANGO_WEIGHT_BOLD, NULL);
63 chat_entry = GTK_ENTRY(
64 gtk_builder_get_object(builder, "ChatEntry"));
65 struct call_send_block_params *send_params =
66 [params->object allocMemoryWithSize: sizeof(*send_params)];
67 send_params->block = params->object.sendBlock;
68 send_params->chat = params->object;
69 g_signal_connect(chat_entry, "key_release_event",
70 G_CALLBACK(call_send_block), send_params);
72 gtk_window_set_title(GTK_WINDOW(params->object.chat_window),
73 [params->title UTF8String]);
74 gtk_widget_show(params->object.chat_window);
76 *params->initialized = YES;
78 g_object_unref(builder);
79 [params->title release];
85 @implementation JubGtkChatUI
86 @synthesize chat_window;
87 @synthesize chat_buffer;
88 @synthesize sendBlock;
89 @synthesize closeBlock;
91 - initWithTitle: (OFString*)title
92 closeBlock: (jub_close_block_t)closeBlock_
93 sendBlock: (jub_send_block_t)sendBlock_
95 volatile BOOL initialized = NO;
99 closeBlock = [closeBlock_ copy];
100 sendBlock = [sendBlock_ copy];
103 struct init_params *params = malloc(sizeof(*params));
104 params->initialized = &initialized;
105 params->title = [title retain];
106 params->object = self;
107 g_idle_add(init, params);
113 while (!initialized);
120 gtk_widget_destroy(chat_window);
122 [closeBlock release];
127 - (void)addMessage: (OFString*)text
128 sender: (OFString*)sender
130 BOOL first = bufferEmpty;
131 if (OF_UNLIKELY(bufferEmpty)) bufferEmpty = NO;
133 g_object_ref(chat_buffer);
136 if (OF_LIKELY(!first))
137 gtk_text_buffer_insert_at_cursor(chat_buffer, "\n", 1);
139 gtk_text_buffer_get_end_iter(chat_buffer, &endIter);
140 gtk_text_buffer_insert_with_tags_by_name(chat_buffer, &endIter,
141 [sender UTF8String], [sender UTF8StringLength], "bold",
143 gtk_text_buffer_get_end_iter(chat_buffer, &endIter);
144 gtk_text_buffer_insert_with_tags_by_name(chat_buffer, &endIter,
145 ": ", 2, "bold", NULL);
147 gtk_text_buffer_insert_at_cursor(chat_buffer, [text UTF8String],
148 [text UTF8StringLength]);
149 g_object_unref(chat_buffer);