--- a/demo/data/demo.ui Thu Jul 11 23:00:56 2019 -0500
+++ b/demo/data/demo.ui Sat Jul 13 04:47:52 2019 -0500
@@ -138,6 +138,7 @@
<object class="GtkToolButton">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Insert HTML from a file</property> <property name="label" translatable="yes">Insert HTML</property>
<property name="use_underline">True</property>
<property name="icon_name">text-html</property>
@@ -152,6 +153,7 @@
<object class="GtkToolButton">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Insert Markdown from a file</property> <property name="label" translatable="yes">Insert Markdown</property>
<property name="use_underline">True</property>
<property name="icon_name">text-x-generic</property>
@@ -162,6 +164,42 @@
<property name="homogeneous">True</property>
+ <object class="GtkSeparatorToolItem"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="expand">False</property> + <property name="homogeneous">True</property> + <object class="GtkToggleToolButton" id="toggle_toolbar"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="tooltip_text" translatable="yes">Toogle toolbar visibility</property> + <property name="label" translatable="yes">Toolbar</property> + <property name="use_underline">True</property> + <property name="expand">False</property> + <property name="homogeneous">True</property> + <object class="GtkToggleToolButton" id="toggle_send_button"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="tooltip_text" translatable="yes">Toggle send button visibility</property> + <property name="label" translatable="yes">Send Button</property> + <property name="use_underline">True</property> + <property name="expand">False</property> + <property name="homogeneous">True</property> <property name="expand">False</property>
--- a/demo/talkatudemowindow.c Thu Jul 11 23:00:56 2019 -0500
+++ b/demo/talkatudemowindow.c Sat Jul 13 04:47:52 2019 -0500
@@ -32,6 +32,9 @@
GtkRadioToolButton *toggle_html;
GtkRadioToolButton *toggle_markdown;
+ GtkToggleToolButton *toggle_toolbar; + GtkToggleToolButton *toggle_send_button; GtkTextBuffer *buffer_plain;
GtkTextBuffer *buffer_whole;
GtkTextBuffer *buffer_html;
@@ -224,6 +227,18 @@
gtk_widget_init_template(GTK_WIDGET(window));
gtk_text_view_set_buffer(GTK_TEXT_VIEW(window->view_history), window->buffer_history);
+ g_object_bind_property( + window->editor, "show-toolbar", + window->toggle_toolbar, "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL + g_object_bind_property( + window->editor, "show-send-button", + window->toggle_send_button, "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL @@ -249,6 +264,9 @@
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, toggle_toolbar); + gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, toggle_send_button); gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_closed_cb);
gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_buffer_changed_cb);
gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_view_open_url_cb);
--- a/talkatu/data/editor.ui Thu Jul 11 23:00:56 2019 -0500
+++ b/talkatu/data/editor.ui Sat Jul 13 04:47:52 2019 -0500
@@ -23,20 +23,45 @@
- <object class="GtkScrolledWindow">
+ <object class="GtkBox"> <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">never</property>
- <property name="shadow_type">in</property>
+ <property name="can_focus">False</property> + <property name="spacing">4</property> - <object class="TalkatuView" id="view">
+ <object class="GtkScrolledWindow"> <property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="wrap_mode">word</property>
- <property name="buffer">buffer</property>
- <signal name="notify::buffer" handler="talkatu_editor_view_buffer_changed_handler" object="TalkatuEditor" swapped="no"/>
+ <property name="hscrollbar_policy">never</property> + <property name="shadow_type">in</property> + <object class="TalkatuView" id="view"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="wrap_mode">word</property> + <property name="buffer">buffer</property> + <signal name="notify::buffer" handler="talkatu_editor_view_buffer_changed_handler" object="TalkatuEditor" swapped="no"/> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + <object class="GtkButton" id="send_button"> + <property name="label" translatable="yes">Send</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <signal name="clicked" handler="talkatu_editor_send_button_clicked_cb" object="TalkatuEditor" swapped="no"/> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> --- a/talkatu/talkatueditor.c Thu Jul 11 23:00:56 2019 -0500
+++ b/talkatu/talkatueditor.c Sat Jul 13 04:47:52 2019 -0500
@@ -36,8 +36,21 @@
+ GtkWidget *send_button; +static GParamSpec *properties[N_PROPERTIES] = {NULL, }; G_DEFINE_TYPE(TalkatuEditor, talkatu_editor, GTK_TYPE_BOX)
/******************************************************************************
@@ -63,18 +76,125 @@
talkatu_editor_buffer_changed(TALKATU_EDITOR(data));
+talkatu_editor_send_button_clicked_cb(GtkButton *button, gpointer data) { + TalkatuEditor *editor = TALKATU_EDITOR(data); + talkatu_view_send_message(TALKATU_VIEW(editor->view)); + gtk_widget_grab_focus(editor->view); /******************************************************************************
*****************************************************************************/
+talkatu_editor_get_property(GObject *obj, guint param_id, GValue *value, GParamSpec *pspec) { + TalkatuEditor *editor = TALKATU_EDITOR(obj); + g_value_set_object(value, talkatu_editor_get_toolbar(editor)); + case PROP_SHOW_TOOLBAR: + g_value_set_boolean(value, talkatu_editor_get_toolbar_visible(editor)); + g_value_set_object(value, talkatu_editor_get_view(editor)); + case PROP_SHOW_SEND_BUTTON: + g_value_set_boolean(value, talkatu_editor_get_send_button_visible(editor)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +talkatu_editor_set_property(GObject *obj, guint param_id, const GValue *value, GParamSpec *pspec) { + TalkatuEditor *editor = TALKATU_EDITOR(obj); + case PROP_SHOW_TOOLBAR: + talkatu_editor_set_toolbar_visible(editor, g_value_get_boolean(value)); + talkatu_editor_set_buffer(editor, g_value_get_object(value)); + case PROP_SHOW_SEND_BUTTON: + talkatu_editor_set_send_button_visible(editor, g_value_get_boolean(value)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); talkatu_editor_init(TalkatuEditor *editor) {
gtk_widget_init_template(GTK_WIDGET(editor));
+ /* bind the visibility of the toolbar to the editor property */ + g_object_bind_property( + editor, "show-toolbar", + editor->toolbar, "visible", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL + /* bind the visibility of the send button to the editor property */ + g_object_bind_property( + editor, "show-send-button", + editor->send_button, "visible", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL talkatu_editor_class_init(TalkatuEditorClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+ obj_class->get_property = talkatu_editor_get_property; + obj_class->set_property = talkatu_editor_set_property; + properties[PROP_TOOLBAR] = g_param_spec_object( + properties[PROP_SHOW_TOOLBAR] = g_param_spec_boolean( + "show-toolbar", "show-toolbar", + "Whether or not to show the toolbar", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT + properties[PROP_VIEW] = g_param_spec_object( + properties[PROP_BUFFER] = g_param_spec_object( + "The GtkTextBuffer for the view", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT + properties[PROP_SHOW_SEND_BUTTON] = g_param_spec_boolean( + "show-send-button", "show-send-button", + "Whether or not to show the send button", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT + g_object_class_install_properties(obj_class, N_PROPERTIES, properties); gtk_widget_class_set_template_from_resource(
@@ -83,8 +203,11 @@
gtk_widget_class_bind_template_child_internal(widget_class, TalkatuEditor, view);
gtk_widget_class_bind_template_child_internal(widget_class, TalkatuEditor, toolbar);
+ gtk_widget_class_bind_template_child_internal(widget_class, TalkatuEditor, send_button); gtk_widget_class_bind_template_callback(widget_class, talkatu_editor_view_buffer_changed_handler);
+ gtk_widget_class_bind_template_callback(widget_class, talkatu_editor_send_button_clicked_cb); /******************************************************************************
@@ -104,6 +227,80 @@
+ * talkatu_editor_get_toolbar: + * @editor: The #TalkatuEditor instance. + * Gets the #TalkatuToolbar that @editor is using. + * Returns: (transfer none): The #TalkatuToolbar that @editor is using. +talkatu_editor_get_toolbar(TalkatuEditor *editor) { + g_return_val_if_fail(TALKATU_IS_EDITOR(editor), NULL); + return editor->toolbar; + * talkatu_editor_set_toolbar_visible: + * @editor: The #TalkatuEditor instance. + * @visible: Whether or not the toolbar should be visible. + * Makes the toolbar visible if @visible is %TRUE otherwise hides it. +talkatu_editor_set_toolbar_visible(TalkatuEditor *editor, gboolean visible) { + g_return_if_fail(TALKATU_IS_EDITOR(editor)); + gtk_widget_set_visible(editor->toolbar, visible); + * talkatu_editor_get_toolbar_visible: + * @editor: The #TalkatuEditor instance. + * Returns whether or not the toolbar is visible. + * Returns: %TRUE if the toolbar is visible, %FALSE otherwise. +talkatu_editor_get_toolbar_visible(TalkatuEditor *editor) { + g_return_val_if_fail(TALKATU_IS_EDITOR(editor), FALSE); + return gtk_widget_get_visible(editor->toolbar); + * talkatu_editor_show_toolbar: + * @editor: The #TalkatuEditor instance. + * Shows the toolbar inside of @editor if it was previously hidden. + * Deprecated: use #talkatu_editor_set_toolbar_visible instead. +talkatu_editor_show_toolbar(TalkatuEditor *editor) { + g_return_if_fail(TALKATU_IS_EDITOR(editor)); + gtk_widget_show(editor->toolbar); + * talkatu_editor_hide_toolbar: + * @editor: The #TalkatuEditor instance. + * Hides the toolbar inside of @editor if it is currently visible. + * Deprecated: use #talkatu_editor_set_toolbar_visible instead. +talkatu_editor_hide_toolbar(TalkatuEditor *editor) { + g_return_if_fail(TALKATU_IS_EDITOR(editor)); + gtk_widget_hide(editor->toolbar); * talkatu_editor_get_view:
* @editor: The #TalkatuEditor instance.
@@ -119,42 +316,59 @@
- * talkatu_editor_get_toolbar:
+ * talkatu_editor_get_buffer: * @editor: The #TalkatuEditor instance.
- * Gets the #TalkatuToolbar that @editor is using.
+ * Gets the #GtkTextBuffer for the internal view. - * Returns: (transfer none): The #TalkatuToolbar that @editor is using.
+ * Returns: (transfer none): The #GtkTextBuffer for the internal view.
-talkatu_editor_get_toolbar(TalkatuEditor *editor) {
+talkatu_editor_get_buffer(TalkatuEditor *editor) { g_return_val_if_fail(TALKATU_IS_EDITOR(editor), NULL);
- return editor->toolbar;
+ return gtk_text_view_get_buffer(GTK_TEXT_VIEW(editor->view)); - * talkatu_editor_show_toolbar:
+ * talkatu_editor_set_buffer: * @editor: The #TalkatuEditor instance.
+ * @buffer: A new #GtkTextBuffer to use. - * Shows the toolbar inside of @editor if it was previously hidden.
+ * Sets the #GtkTextBuffer for the internal view to @buffer. -talkatu_editor_show_toolbar(TalkatuEditor *editor) {
+talkatu_editor_set_buffer(TalkatuEditor *editor, GtkTextBuffer *buffer) { g_return_if_fail(TALKATU_IS_EDITOR(editor));
- gtk_widget_show(editor->toolbar);
+ gtk_text_view_set_buffer(GTK_TEXT_VIEW(editor->view), buffer); - * talkatu_editor_hide_toolbar:
+ * talkatu_editor_get_send_button_visible: * @editor: The #TalkatuEditor instance.
- * Hides the toolbar inside of @editor if it is currently visible.
+ * Returns whether or not the send button is visible. + * Returns: %TRUE if the send button is visible, %FALSE otherwise. +talkatu_editor_get_send_button_visible(TalkatuEditor *editor) { + g_return_val_if_fail(TALKATU_IS_EDITOR(editor), FALSE); + return gtk_widget_get_visible(editor->send_button); + * talkatu_editor_set_send_button_visible: + * @editor: The #TalkatuEditor instance. + * @visible: Whether or not the send button should be visible. + * Sets the visibility of the send button depending on @visible. -talkatu_editor_hide_toolbar(TalkatuEditor *editor) {
+talkatu_editor_set_send_button_visible(TalkatuEditor *editor, gboolean visible) { g_return_if_fail(TALKATU_IS_EDITOR(editor));
- gtk_widget_hide(editor->toolbar);
+ gtk_widget_set_visible(editor->send_button, visible); --- a/talkatu/talkatueditor.h Thu Jul 11 23:00:56 2019 -0500
+++ b/talkatu/talkatueditor.h Sat Jul 13 04:47:52 2019 -0500
@@ -30,18 +30,25 @@
-#define TALKATU_TYPE_EDITOR (talkatu_editor_get_type())
+#define TALKATU_TYPE_EDITOR (talkatu_editor_get_type()) G_DECLARE_FINAL_TYPE(TalkatuEditor, talkatu_editor, TALKATU, EDITOR, GtkBox)
GtkWidget *talkatu_editor_new(void);
-GtkWidget *talkatu_editor_get_view(TalkatuEditor *editor);
GtkWidget *talkatu_editor_get_toolbar(TalkatuEditor *editor);
+void talkatu_editor_set_toolbar_visible(TalkatuEditor *editor, gboolean visible); +gboolean talkatu_editor_get_toolbar_visible(TalkatuEditor *editor); void talkatu_editor_show_toolbar(TalkatuEditor *editor);
void talkatu_editor_hide_toolbar(TalkatuEditor *editor);
+GtkWidget *talkatu_editor_get_view(TalkatuEditor *editor); +GtkTextBuffer *talkatu_editor_get_buffer(TalkatuEditor *editor); +void talkatu_editor_set_buffer(TalkatuEditor *editor, GtkTextBuffer *buffer); +gboolean talkatu_editor_get_send_button_visible(TalkatuEditor *editor); +void talkatu_editor_set_send_button_visible(TalkatuEditor *editor, gboolean visible); #endif /* TALKATU_EDITOR_H */
--- a/talkatu/talkatuview.c Thu Jul 11 23:00:56 2019 -0500
+++ b/talkatu/talkatuview.c Sat Jul 13 04:47:52 2019 -0500
@@ -156,7 +156,7 @@
TalkatuViewPrivate *priv = talkatu_view_get_instance_private(view);
if((priv->send_binding & binding) != 0) {
- g_signal_emit(view, signals[SIG_SEND_MESSAGE], 0);
+ talkatu_view_send_message(view); } else if(gtk_text_view_get_editable(GTK_TEXT_VIEW(view))) {
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
@@ -184,10 +184,10 @@
-talkatu_view_emit_send_message_cb(GtkMenuItem *item, gpointer data) {
- TalkatuView *view = TALKATU_VIEW(data);
+talkatu_view_send_message_cb(GtkMenuItem *item, gpointer data) { + talkatu_view_send_message(TALKATU_VIEW(data)); - g_signal_emit(view, signals[SIG_SEND_MESSAGE], 0);
+ gtk_widget_grab_focus(GTK_WIDGET(data)); @@ -239,7 +239,7 @@
- G_CALLBACK(talkatu_view_emit_send_message_cb),
+ G_CALLBACK(talkatu_view_send_message_cb), gtk_menu_shell_insert(GTK_MENU_SHELL(popup), item, pos++);
@@ -516,3 +516,18 @@
return priv->send_binding;
+ * talkatu_view_send_message: + * @view: The #TalkatuView instance. + * Emits the signal that @view is trying to send a message. This is used for + * cases like the optional send button in #TalkatuEditor and other instances + * where the user has performed an actions to send a message. +talkatu_view_send_message(TalkatuView *view) { + g_return_if_fail(TALKATU_IS_VIEW(view)); + g_signal_emit(view, signals[SIG_SEND_MESSAGE], 0); \ No newline at end of file
--- a/talkatu/talkatuview.h Thu Jul 11 23:00:56 2019 -0500
+++ b/talkatu/talkatuview.h Sat Jul 13 04:47:52 2019 -0500
@@ -61,6 +61,8 @@
void talkatu_view_set_send_binding(TalkatuView *view, TalkatuViewSendBinding bindings);
TalkatuViewSendBinding talkatu_view_get_send_binding(TalkatuView *view);
+void talkatu_view_send_message(TalkatuView *view); #endif /* TALKATU_VIEW_H */