messenger-gtk

Gtk+3 graphical user interfaces for GNUnet Messenger
Log | Files | Refs | Submodules | README | LICENSE

commit 74268f92c68c98757c16a7bce3b253297567744c
parent a0554cc463f6b7c4ca7d2704da213a71fe28900b
Author: Jacki <jacki@thejackimonster.de>
Date:   Thu, 18 Jan 2024 01:08:15 +0100

Add popover for sending text options

Signed-off-by: Jacki <jacki@thejackimonster.de>

Diffstat:
Mresources/ui/chat.ui | 40++++++++++++++++++++++++++++++++++++++++
Mresources/ui/play_media.ui | 1+
Msrc/ui/chat.c | 126++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/ui/chat.h | 8++++++++
Msrc/ui/chat_entry.c | 1-
Msrc/ui/message.c | 4++++
Msrc/ui/picker.c | 8++++----
7 files changed, 172 insertions(+), 16 deletions(-)

diff --git a/resources/ui/chat.ui b/resources/ui/chat.ui @@ -1046,4 +1046,44 @@ Author: Tobias Frisch </object> </child> </object> + <object class="GtkPopover" id="send_popover"> + <property name="can-focus">False</property> + <property name="relative-to">send_record_button</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkButton" id="send_later_button"> + <property name="label" translatable="yes">Send later</property> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="relief">none</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="send_now_button"> + <property name="label" translatable="yes">Send now</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="relief">none</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> </interface> diff --git a/resources/ui/play_media.ui b/resources/ui/play_media.ui @@ -316,6 +316,7 @@ audio-volume-medium-symbolic</property> <child> <object class="GtkButton" id="settings_button"> <property name="visible">True</property> + <property name="sensitive">False</property> <property name="can-focus">True</property> <property name="receives-default">True</property> <property name="relief">none</property> diff --git a/src/ui/chat.c b/src/ui/chat.c @@ -472,7 +472,9 @@ handle_send_text_buffer_changed(GtkTextBuffer *buffer, static gboolean _send_text_from_view(MESSENGER_Application *app, - GtkTextView *text_view) + UI_CHAT_Handle *handle, + GtkTextView *text_view, + gint64 action_time) { GtkTextBuffer *buffer = gtk_text_view_get_buffer(text_view); @@ -485,6 +487,12 @@ _send_text_from_view(MESSENGER_Application *app, if (0 == strlen(text)) return FALSE; + if (action_time >= UI_CHAT_SEND_BUTTON_HOLD_INTERVAL) + { + gtk_popover_popup(handle->send_popover); + return FALSE; + } + struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) ( g_object_get_qdata(G_OBJECT(text_view), app->quarks.data) ); @@ -589,7 +597,51 @@ handle_send_record_button_click(GtkButton *button, g_object_get_qdata(G_OBJECT(button), app->quarks.widget) ); - _send_text_from_view(app, text_view); + _send_text_from_view(app, handle, text_view, handle->send_pressed_time); +} + +static void +handle_send_later_button_click(GtkButton *button, + gpointer user_data) +{ + MESSENGER_Application *app = (MESSENGER_Application*) user_data; + + UI_CHAT_Handle *handle = (UI_CHAT_Handle*) ( + g_object_get_qdata(G_OBJECT(button), app->quarks.ui) + ); + + handle->send_pressed_time = 0; + + if (gtk_widget_is_visible(GTK_WIDGET(handle->send_popover))) + gtk_popover_popdown(handle->send_popover); + + if (gtk_stack_get_visible_child(handle->send_stack) != handle->send_text_box) + return; + + // TODO +} + +static void +handle_send_now_button_click(GtkButton *button, + gpointer user_data) +{ + MESSENGER_Application *app = (MESSENGER_Application*) user_data; + + UI_CHAT_Handle *handle = (UI_CHAT_Handle*) ( + g_object_get_qdata(G_OBJECT(button), app->quarks.ui) + ); + + if (gtk_widget_is_visible(GTK_WIDGET(handle->send_popover))) + gtk_popover_popdown(handle->send_popover); + + if (gtk_stack_get_visible_child(handle->send_stack) != handle->send_text_box) + return; + + GtkTextView *text_view = GTK_TEXT_VIEW( + g_object_get_qdata(G_OBJECT(handle->send_record_button), app->quarks.widget) + ); + + _send_text_from_view(app, handle, text_view, 0); } static gboolean @@ -603,6 +655,12 @@ handle_send_record_button_pressed(GtkWidget *widget, g_object_get_qdata(G_OBJECT(widget), app->quarks.widget) ); + UI_CHAT_Handle *handle = (UI_CHAT_Handle*) ( + g_object_get_qdata(G_OBJECT(widget), app->quarks.ui) + ); + + handle->send_pressed_time = g_get_monotonic_time(); + GtkTextBuffer *buffer = gtk_text_view_get_buffer(text_view); GtkTextIter start, end; @@ -614,10 +672,6 @@ handle_send_record_button_pressed(GtkWidget *widget, if (0 < strlen(text)) return FALSE; - UI_CHAT_Handle *handle = (UI_CHAT_Handle*) ( - g_object_get_qdata(G_OBJECT(widget), app->quarks.ui) - ); - if ((handle->recorded) || (!(handle->record_pipeline)) || (handle->recording_filename[0]) || (gtk_revealer_get_child_revealed(handle->picker_revealer)) || @@ -680,6 +734,12 @@ handle_send_record_button_released(GtkWidget *widget, g_object_get_qdata(G_OBJECT(widget), app->quarks.widget) ); + UI_CHAT_Handle *handle = (UI_CHAT_Handle*) ( + g_object_get_qdata(G_OBJECT(widget), app->quarks.ui) + ); + + handle->send_pressed_time = g_get_monotonic_time() - handle->send_pressed_time; + GtkTextBuffer *buffer = gtk_text_view_get_buffer(text_view); GtkTextIter start, end; @@ -691,10 +751,6 @@ handle_send_record_button_released(GtkWidget *widget, if (0 < strlen(text)) return FALSE; - UI_CHAT_Handle *handle = (UI_CHAT_Handle*) ( - g_object_get_qdata(G_OBJECT(widget), app->quarks.ui) - ); - if ((handle->recorded) || (!(handle->record_pipeline)) || (!(handle->recording_filename[0])) || (gtk_revealer_get_child_revealed(handle->picker_revealer)) || @@ -728,8 +784,12 @@ handle_send_text_key_press (GtkWidget *widget, ((event->keyval != GDK_KEY_Return) && (event->keyval != GDK_KEY_KP_Enter))) return FALSE; + + UI_CHAT_Handle *handle = (UI_CHAT_Handle*) ( + g_object_get_qdata(G_OBJECT(widget), app->quarks.ui) + ); - return _send_text_from_view(app, GTK_TEXT_VIEW(widget)); + return _send_text_from_view(app, handle, GTK_TEXT_VIEW(widget), 0); } static void @@ -1269,6 +1329,18 @@ ui_chat_new(MESSENGER_Application *app) gtk_builder_get_object(handle->builder, "send_record_symbol") ); + handle->send_popover = GTK_POPOVER( + gtk_builder_get_object(handle->builder, "send_popover") + ); + + handle->send_now_button = GTK_BUTTON( + gtk_builder_get_object(handle->builder, "send_now_button") + ); + + handle->send_later_button = GTK_BUTTON( + gtk_builder_get_object(handle->builder, "send_later_button") + ); + GtkTextBuffer *send_text_buffer = gtk_text_view_get_buffer( handle->send_text_view ); @@ -1288,6 +1360,20 @@ ui_chat_new(MESSENGER_Application *app) ); g_signal_connect( + handle->send_later_button, + "clicked", + G_CALLBACK(handle_send_later_button_click), + app + ); + + g_signal_connect( + handle->send_now_button, + "clicked", + G_CALLBACK(handle_send_now_button_click), + app + ); + + g_signal_connect( handle->send_record_button, "button-press-event", G_CALLBACK(handle_send_record_button_pressed), @@ -1327,11 +1413,29 @@ ui_chat_new(MESSENGER_Application *app) ); g_object_set_qdata( + G_OBJECT(handle->send_text_view), + app->quarks.ui, + handle + ); + + g_object_set_qdata( G_OBJECT(handle->send_record_button), app->quarks.ui, handle ); + g_object_set_qdata( + G_OBJECT(handle->send_later_button), + app->quarks.ui, + handle + ); + + g_object_set_qdata( + G_OBJECT(handle->send_now_button), + app->quarks.ui, + handle + ); + handle->recording_close_button = GTK_BUTTON( gtk_builder_get_object(handle->builder, "recording_close_button") ); diff --git a/src/ui/chat.h b/src/ui/chat.h @@ -33,6 +33,8 @@ #include <gnunet/gnunet_chat_lib.h> +#define UI_CHAT_SEND_BUTTON_HOLD_INTERVAL 500000 // in microseconds + typedef struct MESSENGER_Application MESSENGER_Application; typedef struct UI_MESSAGE_Handle UI_MESSAGE_Handle; typedef struct UI_PICKER_Handle UI_PICKER_Handle; @@ -40,6 +42,8 @@ typedef struct UI_FILE_LOAD_ENTRY_Handle UI_FILE_LOAD_ENTRY_Handle; typedef struct UI_CHAT_Handle { + gint64 send_pressed_time; + gboolean recorded; gboolean playing; @@ -122,6 +126,10 @@ typedef struct UI_CHAT_Handle GtkButton *send_record_button; GtkImage *send_record_symbol; + GtkPopover *send_popover; + GtkButton *send_later_button; + GtkButton *send_now_button; + GtkButton *recording_close_button; GtkButton *recording_play_button; GtkImage *play_pause_symbol; diff --git a/src/ui/chat_entry.c b/src/ui/chat_entry.c @@ -27,7 +27,6 @@ #include "message.h" #include "../application.h" -#include "../contact.h" #include "../ui.h" #include <gnunet/gnunet_chat_lib.h> #include <gnunet/gnunet_time_lib.h> diff --git a/src/ui/message.c b/src/ui/message.c @@ -517,6 +517,10 @@ _message_media_supports_file_extension(const gchar *filename) if (0 == g_strcmp0(extension, ".ogg")) return TRUE; + if (0 == g_strcmp0(extension, ".mp3")) + return TRUE; + if (0 == g_strcmp0(extension, ".wav")) + return TRUE; return FALSE; } diff --git a/src/ui/picker.c b/src/ui/picker.c @@ -32,7 +32,7 @@ static void handle_emoji_button_click(GtkButton *button, - gpointer user_data) + gpointer user_data) { GtkTextView *text_view = GTK_TEXT_VIEW(user_data); GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(text_view); @@ -45,9 +45,9 @@ handle_emoji_button_click(GtkButton *button, static void _add_emoji_buttons(GtkFlowBox *flow_box, - GtkTextView *text_view, - size_t characters_count, - const uint32_t *characters) + GtkTextView *text_view, + size_t characters_count, + const uint32_t *characters) { glong items_written; GError *error;