1 #import "JubGtkChatUI.h"
2 #import "JubGtkHelper.h"
4 struct call_send_block_params {
5 jub_send_block_t block;
9 static void call_send_block(GtkEntry *entry, gpointer data)
11 struct call_send_block_params *params = data;
14 [[OFString alloc] initWithUTF8String: gtk_entry_get_text(entry)];
16 if ([text length] > 0) {
17 gtk_entry_set_text(entry, "");
19 [params->chat addMessage: text
26 static void call_close_block(GtkWidget *object, gpointer data)
28 jub_close_block_t block = data;
32 @implementation JubGtkChatUI
33 - initWithTitle: (OFString*)title
34 closeBlock: (jub_close_block_t)closeBlock
35 sendBlock: (jub_send_block_t)sendBlock
40 __block volatile bool initialized = false;
41 __block GtkWidget *chat_window;
42 __block GtkTextBuffer *chat_buffer;
44 _closeBlock = [closeBlock copy];
45 _sendBlock = [sendBlock copy];
51 GtkBuilder *builder = gtk_builder_new();
52 gtk_builder_add_from_file(builder, "data/gtk/chat.ui",
55 chat_window = GTK_WIDGET(
56 gtk_builder_get_object(builder, "ChatWindow"));
57 g_signal_connect(chat_window, "destroy",
58 G_CALLBACK(call_close_block), _closeBlock);
60 _chat_view = GTK_TEXT_VIEW(
61 gtk_builder_get_object(builder, "ChatTextView"));
62 chat_buffer = gtk_text_view_get_buffer(_chat_view);
63 gtk_text_buffer_create_tag(chat_buffer, "bold",
64 "weight", PANGO_WEIGHT_BOLD, NULL);
66 chat_entry = GTK_ENTRY(
67 gtk_builder_get_object(builder, "ChatEntry"));
68 struct call_send_block_params *send_params =
69 [self allocMemoryWithSize: sizeof(*send_params)];
70 send_params->block = _sendBlock;
71 send_params->chat = self;
72 g_signal_connect(chat_entry, "activate",
73 G_CALLBACK(call_send_block), send_params);
75 gtk_window_set_title(GTK_WINDOW(chat_window),
77 gtk_widget_show(chat_window);
81 g_object_unref(builder);
86 _chat_buffer = chat_buffer;
87 _chat_window = chat_window;
98 gtk_widget_destroy(_chat_window);
100 [_closeBlock release];
105 - (void)addMessage: (OFString*)text
106 sender: (OFString*)sender
108 bool first = _bufferEmpty;
109 if (OF_UNLIKELY(_bufferEmpty)) _bufferEmpty = false;
112 GtkTextIter end_iter;
113 GtkTextMark *insert_mark =
114 gtk_text_buffer_get_insert(_chat_buffer);
116 if (OF_LIKELY(!first))
117 gtk_text_buffer_insert_at_cursor(_chat_buffer, "\n", 1);
119 gtk_text_buffer_get_end_iter(_chat_buffer, &end_iter);
120 gtk_text_buffer_insert_with_tags_by_name(_chat_buffer,
121 &end_iter, [sender UTF8String], [sender UTF8StringLength],
123 gtk_text_buffer_get_end_iter(_chat_buffer, &end_iter);
124 gtk_text_buffer_insert_with_tags_by_name(_chat_buffer,
125 &end_iter, ": ", 2, "bold", NULL);
127 gtk_text_buffer_insert_at_cursor(_chat_buffer,
128 [text UTF8String], [text UTF8StringLength]);
130 gtk_text_view_scroll_to_mark(_chat_view, insert_mark, 0,