qulogic/talkatu

Parents af031d87de82
Children 8628c3e3936a
Initial basics for this history buffer/view as well as multiple user support for the demo app. Fixes #31, #6
--- a/demo/data/demo.ui Mon Jul 15 07:02:07 2019 +0000
+++ b/demo/data/demo.ui Fri Jul 12 06:16:40 2019 -0500
@@ -3,6 +3,76 @@
<interface>
<requires lib="Talkatu" version="0.0"/>
<requires lib="gtk+" version="3.10"/>
+ <object class="GtkMenu" id="author_menu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkRadioMenuItem" id="author_menu_item">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Alice</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_as_radio">True</property>
+ <signal name="activate" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioMenuItem">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Bob</property>
+ <property name="use_underline">True</property>
+ <property name="draw_as_radio">True</property>
+ <property name="group">author_menu_item</property>
+ <signal name="activate" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioMenuItem">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Carlos</property>
+ <property name="use_underline">True</property>
+ <property name="draw_as_radio">True</property>
+ <property name="group">author_menu_item</property>
+ <signal name="activate" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioMenuItem">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Eve</property>
+ <property name="use_underline">True</property>
+ <property name="draw_as_radio">True</property>
+ <property name="group">author_menu_item</property>
+ <signal name="activate" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioMenuItem">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">David</property>
+ <property name="use_underline">True</property>
+ <property name="draw_as_radio">True</property>
+ <property name="group">author_menu_item</property>
+ <signal name="activate" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioMenuItem">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Mallory</property>
+ <property name="use_underline">True</property>
+ <property name="draw_as_radio">True</property>
+ <property name="group">author_menu_item</property>
+ <signal name="activate" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
+ </object>
+ </child>
+ </object>
<object class="TalkatuTagTable" id="table_history"/>
<object class="TalkatuHistoryBuffer" id="buffer_history">
<property name="tag_table">table_history</property>
@@ -24,6 +94,9 @@
<property name="border_width">12</property>
<signal name="delete-event" handler="talkatu_demo_window_closed_cb" swapped="no"/>
<child>
+ <placeholder/>
+ </child>
+ <child>
<object class="GtkPaned">
<property name="visible">True</property>
<property name="can_focus">True</property>
@@ -176,6 +249,29 @@
</packing>
</child>
<child>
+ <object class="GtkMenuToolButton" id="author_button">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Author</property>
+ <property name="use_underline">True</property>
+ <property name="icon_name">system-users</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparatorToolItem">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkToggleToolButton" id="toggle_toolbar">
<property name="visible">True</property>
<property name="can_focus">False</property>
--- a/demo/talkatudemomessage.c Mon Jul 15 07:02:07 2019 +0000
+++ b/demo/talkatudemomessage.c Fri Jul 12 06:16:40 2019 -0500
@@ -21,6 +21,7 @@
GObject parent;
guint64 id;
+ GDateTime *timestamp;
TalkatuContentType content_type;
gchar *author;
gchar *contents;
@@ -34,6 +35,7 @@
PROP_CONTENT_TYPE,
PROP_AUTHOR,
PROP_CONTENTS,
+ PROP_TIMESTAMP,
};
static void
@@ -63,6 +65,20 @@
g_object_notify(G_OBJECT(message), "id");
}
+static GDateTime *
+talkatu_demo_message_get_timestamp(TalkatuDemoMessage *message) {
+ return (message->timestamp) ? g_date_time_ref(message->timestamp) : NULL;
+}
+
+static void
+talkatu_demo_message_set_timestamp(TalkatuDemoMessage *message, GDateTime *timestamp) {
+ g_clear_pointer(&message->timestamp, g_date_time_unref);
+
+ if(timestamp) {
+ message->timestamp = g_date_time_ref(timestamp);
+ }
+}
+
static TalkatuContentType
talkatu_demo_message_get_content_type(TalkatuDemoMessage *message) {
return message->content_type;
@@ -118,6 +134,9 @@
case PROP_ID:
g_value_set_uint64(value, talkatu_demo_message_get_id(message));
break;
+ case PROP_TIMESTAMP:
+ g_value_set_pointer(value, talkatu_demo_message_get_timestamp(message));
+ break;
case PROP_CONTENT_TYPE:
g_value_set_enum(value, talkatu_demo_message_get_content_type(message));
break;
@@ -145,6 +164,9 @@
case PROP_ID:
talkatu_demo_message_set_id(message, g_value_get_uint64(value));
break;
+ case PROP_TIMESTAMP:
+ talkatu_demo_message_set_timestamp(message, g_value_get_pointer(value));
+ break;
case PROP_CONTENT_TYPE:
talkatu_demo_message_set_content_type(message, g_value_get_enum(value));
break;
@@ -164,6 +186,7 @@
talkatu_demo_message_finalize(GObject *obj) {
TalkatuDemoMessage *message = TALKATU_DEMO_MESSAGE(obj);
+ talkatu_demo_message_set_timestamp(message, NULL);
talkatu_demo_message_set_author(message, NULL);
talkatu_demo_message_set_contents(message, NULL);
@@ -183,6 +206,7 @@
obj_class->finalize = talkatu_demo_message_finalize;
g_object_class_override_property(obj_class, PROP_ID, "id");
+ g_object_class_override_property(obj_class, PROP_TIMESTAMP, "timestamp");
g_object_class_override_property(obj_class, PROP_CONTENT_TYPE, "content-type");
g_object_class_override_property(obj_class, PROP_AUTHOR, "author");
g_object_class_override_property(obj_class, PROP_CONTENTS, "contents");
@@ -196,12 +220,20 @@
const gchar *author,
const gchar *contents)
{
- return TALKATU_MESSAGE(g_object_new(
+ GObject *obj = NULL;
+ GDateTime *timestamp = g_date_time_new_now_local();
+
+ obj = g_object_new(
TALKATU_TYPE_DEMO_MESSAGE,
"id", id,
+ "timestamp", timestamp,
"content-type", content_type,
"author", author,
"contents", contents,
NULL
- ));
+ );
+
+ g_date_time_unref(timestamp);
+
+ return TALKATU_MESSAGE(obj);
}
--- a/demo/talkatudemowindow.c Mon Jul 15 07:02:07 2019 +0000
+++ b/demo/talkatudemowindow.c Fri Jul 12 06:16:40 2019 -0500
@@ -40,6 +40,11 @@
GtkTextBuffer *buffer_html;
GtkTextBuffer *buffer_markdown;
GtkTextBuffer *buffer_history;
+
+ GtkWidget *author_button;
+ GtkWidget *author_menu;
+ GtkWidget *author_menu_item;
+ gchar *author;
};
G_DEFINE_TYPE(TalkatuDemoWindow, talkatu_demo_window, GTK_TYPE_WINDOW);
@@ -201,7 +206,7 @@
message = talkatu_demo_message_new(
id++,
content_type,
- "window1",
+ window->author,
plain_text
);
g_free(plain_text);
@@ -222,6 +227,14 @@
return FALSE;
}
+static void
+talkatu_demo_window_author_changed(GtkMenuItem *item, gpointer data) {
+ TalkatuDemoWindow *window = TALKATU_DEMO_WINDOW(data);
+
+ g_clear_pointer(&window->author, g_free);
+ window->author = g_strdup(gtk_menu_item_get_label(item));
+}
+
/******************************************************************************
* GObject Implementation
*****************************************************************************/
@@ -231,6 +244,13 @@
gtk_text_view_set_buffer(GTK_TEXT_VIEW(window->view_history), window->buffer_history);
+ gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(window->author_button), window->author_menu);
+
+ /* activate the first menu item to make sure it's label gets stored
+ * correctly.
+ */
+ gtk_menu_item_activate(GTK_MENU_ITEM(window->author_menu_item));
+
g_object_bind_property(
window->editor, "show-toolbar",
window->toggle_toolbar, "active",
@@ -267,6 +287,10 @@
gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, toggle_html);
gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, toggle_markdown);
+ gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, author_button);
+ gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, author_menu);
+ gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, author_menu_item);
+
gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, toggle_toolbar);
gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, toggle_send_button);
@@ -277,6 +301,8 @@
gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_insert_html_cb);
gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_insert_markdown_cb);
+
+ gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_author_changed);
}
/******************************************************************************
--- a/talkatu/talkatuhistory.c Mon Jul 15 07:02:07 2019 +0000
+++ b/talkatu/talkatuhistory.c Fri Jul 12 06:16:40 2019 -0500
@@ -1,6 +1,6 @@
/*
* talkatu
- * Copyright (C) 2017-2018 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2017-2019 Gary Kramlich <grim@reaperworld.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -19,7 +19,6 @@
#include <talkatu/talkatuhistory.h>
#include <talkatu/talkatumessage.h>
-#include <talkatu/talkatumessageactions.h>
/**
* SECTION:talkatuhistory
@@ -37,50 +36,12 @@
G_DEFINE_TYPE(TalkatuHistory, talkatu_history, TALKATU_TYPE_VIEW)
/******************************************************************************
- * Signal Handlers
- *****************************************************************************/
-static void
-talkatu_history_buffer_insert_anchor_cb(GtkTextBuffer *textbuffer,
- GtkTextIter *location,
- GtkTextChildAnchor *anchor,
- gpointer user_data)
-{
- gpointer data = NULL;
-
- data = g_object_get_data(G_OBJECT(anchor), "talkatu-message");
- if(data != NULL) {
- GtkTextView *text_view = GTK_TEXT_VIEW(user_data);
- GtkWidget *message_actions = talkatu_message_actions_new(TALKATU_MESSAGE(data));
-
- gtk_text_view_add_child_at_anchor(text_view, message_actions, anchor);
-
- gtk_widget_show_all(message_actions);
- }
-}
-
-static void
-talkatu_history_buffer_set_cb(GObject *view, GParamSpec *pspec, gpointer data) {
- g_signal_connect_after(
- gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)),
- "insert-child-anchor",
- G_CALLBACK(talkatu_history_buffer_insert_anchor_cb),
- view
- );
-}
-
-/******************************************************************************
* GObject Stuff
*****************************************************************************/
static void
talkatu_history_init(TalkatuHistory *history) {
gtk_text_view_set_editable(GTK_TEXT_VIEW(history), FALSE);
-
- g_signal_connect_after(
- G_OBJECT(history),
- "notify::buffer",
- G_CALLBACK(talkatu_history_buffer_set_cb),
- NULL
- );
+ gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(history), FALSE);
}
static void
--- a/talkatu/talkatuhistorybuffer.c Mon Jul 15 07:02:07 2019 +0000
+++ b/talkatu/talkatuhistorybuffer.c Fri Jul 12 06:16:40 2019 -0500
@@ -42,7 +42,7 @@
{
GtkTextBuffer *buffer = GTK_TEXT_BUFFER(talkatu_buffer);
GtkTextIter start, end;
- GtkTextChildAnchor *anchor;
+ GDateTime *timestamp = NULL;
gchar *author = NULL, *contents = NULL;
/* if there's already text in the buffer, insert a newline */
@@ -51,6 +51,23 @@
gtk_text_buffer_insert(buffer, &end, "\n", -1);
}
+ timestamp = talkatu_message_get_timestamp(message);
+ if(timestamp != NULL) {
+ gchar *timestamp_str = g_date_time_format(timestamp, "(%-l:%M %p) ");
+
+ gtk_text_buffer_insert_with_tags_by_name(
+ buffer,
+ &end,
+ timestamp_str,
+ -1,
+ TALKATU_TAG_TIMESTAMP,
+ NULL
+ );
+
+ g_free(timestamp_str);
+ g_date_time_unref(timestamp);
+ }
+
author = talkatu_message_get_author(message);
gtk_text_buffer_insert_with_tags_by_name(
buffer,
@@ -58,6 +75,7 @@
author,
-1,
TALKATU_TAG_BOLD,
+ TALKATU_TAG_AUTHOR,
NULL
);
g_free(author);
@@ -66,22 +84,15 @@
gtk_text_buffer_insert(buffer, &end, " ", -1);
contents = talkatu_message_get_contents(message);
- gtk_text_buffer_insert(buffer, &end, contents, -1);
- g_free(contents);
-
- /* add the anchor that contains the message */
- anchor = gtk_text_child_anchor_new();
- g_object_set_data_full(
- G_OBJECT(anchor),
- "talkatu-message",
- g_object_ref(message),
- g_object_unref
- );
- gtk_text_buffer_insert_child_anchor(
+ gtk_text_buffer_insert_with_tags_by_name(
buffer,
&end,
- anchor
+ contents,
+ -1,
+ TALKATU_TAG_CONTENTS,
+ NULL
);
+ g_free(contents);
}
/******************************************************************************
--- a/talkatu/talkatumessage.h Mon Jul 15 07:02:07 2019 +0000
+++ b/talkatu/talkatumessage.h Fri Jul 12 06:16:40 2019 -0500
@@ -38,8 +38,7 @@
G_BEGIN_DECLS
-#define TALKATU_TYPE_MESSAGE (talkatu_message_get_type())
-
+#define TALKATU_TYPE_MESSAGE (talkatu_message_get_type())
G_DECLARE_INTERFACE(TalkatuMessage, talkatu_message, TALKATU, MESSAGE, GObject)
struct _TalkatuMessageInterface {
--- a/talkatu/talkatutag.h Mon Jul 15 07:02:07 2019 +0000
+++ b/talkatu/talkatutag.h Fri Jul 12 06:16:40 2019 -0500
@@ -50,6 +50,10 @@
#define TALKATU_TAG_DL TALKATU_TAG_PREFIX "description-list"
#define TALKATU_TAG_DT TALKATU_TAG_PREFIX "description-term"
#define TALKATU_TAG_DD TALKATU_TAG_PREFIX "description-definition"
+#define TALKATU_TAG_MESSAGE TALKATU_TAG_PREFIX "message"
+#define TALKATU_TAG_TIMESTAMP TALKATU_TAG_PREFIX "timestamp"
+#define TALKATU_TAG_AUTHOR TALKATU_TAG_PREFIX "author"
+#define TALKATU_TAG_CONTENTS TALKATU_TAG_PREFIX "contents"
#define TALKATU_TAG_FORMATTING_START "-start"
#define TALKATU_TAG_FORMATTING_END "-end"
--- a/talkatu/talkatutagtable.c Mon Jul 15 07:02:07 2019 +0000
+++ b/talkatu/talkatutagtable.c Fri Jul 12 06:16:40 2019 -0500
@@ -44,9 +44,10 @@
static void
talkatu_tag_table_init(TalkatuTagTable *table) {
GdkRGBA color = {0.0, 0.0, 0.0, 0.0};
+ GtkTextTagTable *tag_table = GTK_TEXT_TAG_TABLE(table);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_BOLD,
"weight", PANGO_WEIGHT_BOLD,
@@ -55,7 +56,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_ITALIC,
"style", PANGO_STYLE_ITALIC,
@@ -64,7 +65,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_UNDERLINE,
"underline", PANGO_UNDERLINE_SINGLE,
@@ -73,7 +74,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_STRIKETHROUGH,
"strikethrough", TRUE,
@@ -82,7 +83,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_SUBSCRIPT,
"rise", -5000,
@@ -91,7 +92,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_SUPERSCRIPT,
"rise", 5000,
@@ -100,7 +101,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_PRE,
"family", "Monospace",
@@ -110,7 +111,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_CODE,
"family", "Monospace",
@@ -121,7 +122,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_SEARCH,
"background", "#22FF00",
@@ -131,7 +132,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_H1,
"weight", PANGO_WEIGHT_BOLD,
@@ -144,7 +145,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_H2,
"weight", PANGO_WEIGHT_BOLD,
@@ -155,7 +156,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_H3,
"weight", PANGO_WEIGHT_BOLD,
@@ -166,7 +167,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_H4,
"weight", PANGO_WEIGHT_BOLD,
@@ -176,7 +177,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_H5,
"weight", PANGO_WEIGHT_BOLD,
@@ -187,7 +188,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_H6,
"weight", PANGO_WEIGHT_BOLD,
@@ -199,7 +200,7 @@
gdk_rgba_parse(&color, "#0000FF");
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_ANCHOR,
"foreground-rgba", &color,
@@ -210,7 +211,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_DL,
"display", TALKATU_TAG_DISPLAY_BLOCK,
@@ -220,7 +221,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_DL TALKATU_TAG_FORMATTING_START,
"pixels-above-lines", 12, /* needs to be dynamic the font's point size */
@@ -229,7 +230,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_DL TALKATU_TAG_FORMATTING_END,
"pixels-below-lines", 12, /* needs to be dynamic the font's point size */
@@ -238,7 +239,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_DT,
"display", TALKATU_TAG_DISPLAY_BLOCK,
@@ -247,7 +248,7 @@
);
gtk_text_tag_table_add(
- GTK_TEXT_TAG_TABLE(table),
+ tag_table,
talkatu_tag_new(
TALKATU_TAG_DD,
"left-margin", 40,
@@ -255,6 +256,27 @@
NULL
)
);
+
+ /* these tags are just used as markers and don't provide any formatting */
+ gtk_text_tag_table_add(
+ tag_table,
+ gtk_text_tag_new(TALKATU_TAG_MESSAGE)
+ );
+
+ gtk_text_tag_table_add(
+ tag_table,
+ gtk_text_tag_new(TALKATU_TAG_TIMESTAMP)
+ );
+
+ gtk_text_tag_table_add(
+ tag_table,
+ gtk_text_tag_new(TALKATU_TAG_AUTHOR)
+ );
+
+ gtk_text_tag_table_add(
+ tag_table,
+ gtk_text_tag_new(TALKATU_TAG_CONTENTS)
+ );
}
static void