* Talkatu - GTK widgets for chat applications
* Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this library; if not, see <https://www.gnu.org/licenses/>.
#include <talkatu/talkatueditor.h>
#include <talkatu/talkatubuffer.h>
#include <talkatu/talkatuinput.h>
#include <talkatu/talkatutoolbar.h>
* @Short_description: A simple editor composed of other Talkatu Widgets
* TalkatuEditor is a composite widget of #TalkatuToolbar and #TalkatuView to
* help make them easier to use.
* The standard _get_type macro for #TalkatuEditor.
* A composite widget that contains a #TalkatuToolbar, #TalkatuInput, and an
* optional send button in the common instant messaging input layout.
static GParamSpec *properties[N_PROPERTIES] = {NULL, };
G_DEFINE_TYPE(TalkatuEditor, talkatu_editor, GTK_TYPE_BOX)
/******************************************************************************
*****************************************************************************/
talkatu_editor_buffer_changed(TalkatuEditor *editor) {
GActionGroup *action_group = NULL;
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(editor->input));
if(TALKATU_IS_BUFFER(buffer)) {
action_group = G_ACTION_GROUP(talkatu_buffer_get_action_group(TALKATU_BUFFER(buffer)));
gtk_widget_insert_action_group(editor->toolbar, "talkatu", action_group);
/******************************************************************************
*****************************************************************************/
talkatu_editor_view_buffer_changed_handler(GObject *obj, GParamSpec *pspec, gpointer data) {
talkatu_editor_buffer_changed(TALKATU_EDITOR(data));
talkatu_editor_send_button_clicked_cb(GtkButton *button, gpointer data) {
TalkatuEditor *editor = TALKATU_EDITOR(data);
talkatu_input_send_message(TALKATU_INPUT(editor->input));
gtk_widget_grab_focus(editor->input);
/******************************************************************************
*****************************************************************************/
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));
g_value_set_object(value, talkatu_editor_get_buffer(editor));
g_value_set_boolean(value, talkatu_editor_get_toolbar_visible(editor));
g_value_set_object(value, talkatu_editor_get_input(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);
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 */
editor->toolbar, "visible",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL
/* bind the visibility of the send button to the editor 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_INPUT] = 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(
"/org/imfreedom/keep/talkatu/talkatu/ui/editor.ui"
gtk_widget_class_bind_template_child_internal(widget_class, TalkatuEditor, input);
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);
/******************************************************************************
*****************************************************************************/
* Creates a new #TalkatuEditor with a normal #GtkTextBuffer.
* Returns: (transfer full): The new #TalkatuEditor instance.
talkatu_editor_new(void) {
return GTK_WIDGET(g_object_new(TALKATU_TYPE_EDITOR, NULL));
* 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);
* 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_get_input:
* @editor: The #TalkatuEditor instance.
* Gets the #TalkatuInput that @editor is using.
* Returns: (transfer none): The #TalkatuInput that @editor is using.
talkatu_editor_get_input(TalkatuEditor *editor) {
g_return_val_if_fail(TALKATU_IS_EDITOR(editor), NULL);
* talkatu_editor_get_buffer:
* @editor: The #TalkatuEditor instance.
* Gets the #GtkTextBuffer for the internal input.
* Returns: (transfer none): The #GtkTextBuffer for the internal input.
talkatu_editor_get_buffer(TalkatuEditor *editor) {
g_return_val_if_fail(TALKATU_IS_EDITOR(editor), NULL);
return gtk_text_view_get_buffer(GTK_TEXT_VIEW(editor->input));
* talkatu_editor_set_buffer:
* @editor: The #TalkatuEditor instance.
* @buffer: A new #GtkTextBuffer to use.
* Sets the #GtkTextBuffer for the internal input to @buffer.
talkatu_editor_set_buffer(TalkatuEditor *editor, GtkTextBuffer *buffer) {
g_return_if_fail(TALKATU_IS_EDITOR(editor));
gtk_text_view_set_buffer(GTK_TEXT_VIEW(editor->input), buffer);
* talkatu_editor_get_send_button_visible:
* @editor: The #TalkatuEditor instance.
* 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_set_send_button_visible(TalkatuEditor *editor, gboolean visible) {
g_return_if_fail(TALKATU_IS_EDITOR(editor));
gtk_widget_set_visible(editor->send_button, visible);