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 void call_close_block(GtkWidget *object, gpointer data)
29 jub_close_block_t block = data;
33 @implementation JubGtkChatUI
34 - initWithTitle: (OFString*)title
35 closeBlock: (jub_close_block_t)closeBlock_
36 sendBlock: (jub_send_block_t)sendBlock_
41 __block volatile BOOL initialized = NO;
42 __block GtkWidget *chat_window_;
43 __block GtkTextBuffer *chat_buffer_;
45 closeBlock = [closeBlock_ copy];
46 sendBlock = [sendBlock_ copy];
52 GtkBuilder *builder = gtk_builder_new();
53 gtk_builder_add_from_file(builder, "data/gtk/chat.ui",
56 chat_window_ = GTK_WIDGET(
57 gtk_builder_get_object(builder, "ChatWindow"));
58 g_signal_connect(chat_window_, "destroy",
59 G_CALLBACK(call_close_block), closeBlock);
61 chat_view = GTK_TEXT_VIEW(
62 gtk_builder_get_object(builder, "ChatTextView"));
63 chat_buffer_ = gtk_text_view_get_buffer(chat_view);
64 gtk_text_buffer_create_tag(chat_buffer_, "bold",
65 "weight", PANGO_WEIGHT_BOLD, NULL);
67 chat_entry = GTK_ENTRY(
68 gtk_builder_get_object(builder, "ChatEntry"));
69 struct call_send_block_params *send_params =
70 [self allocMemoryWithSize: sizeof(*send_params)];
71 send_params->block = sendBlock;
72 send_params->chat = self;
73 g_signal_connect(chat_entry, "key_release_event",
74 G_CALLBACK(call_send_block), send_params);
76 gtk_window_set_title(GTK_WINDOW(chat_window_),
78 gtk_widget_show(chat_window_);
82 g_object_unref(builder);
87 chat_buffer = chat_buffer_;
88 chat_window = chat_window_;
99 gtk_widget_destroy(chat_window);
101 [closeBlock release];
106 - (void)addMessage: (OFString*)text
107 sender: (OFString*)sender
109 BOOL first = bufferEmpty;
110 if (OF_UNLIKELY(bufferEmpty)) bufferEmpty = NO;
113 GtkTextIter end_iter;
114 GtkTextMark *insert_mark =
115 gtk_text_buffer_get_insert(chat_buffer);
117 if (OF_LIKELY(!first))
118 gtk_text_buffer_insert_at_cursor(chat_buffer, "\n", 1);
120 gtk_text_buffer_get_end_iter(chat_buffer, &end_iter);
121 gtk_text_buffer_insert_with_tags_by_name(chat_buffer, &end_iter,
122 [sender UTF8String], [sender UTF8StringLength], "bold",
124 gtk_text_buffer_get_end_iter(chat_buffer, &end_iter);
125 gtk_text_buffer_insert_with_tags_by_name(chat_buffer, &end_iter,
126 ": ", 2, "bold", NULL);
128 gtk_text_buffer_insert_at_cursor(chat_buffer, [text UTF8String],
129 [text UTF8StringLength]);
131 gtk_text_view_scroll_to_mark(chat_view, insert_mark, 0,