messenger-gtk

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

commit e4c9d144af70ac32960c5f39d1544becea9d427c
parent 6e8ea55e93938882a12ec67a682b83931d975836
Author: Jacki <jacki@thejackimonster.de>
Date:   Sun, 16 Jun 2024 18:24:29 +0200

Add panels per active subscription to discourse dialog

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

Diffstat:
Mresources/ui.gresource.xml | 1+
Msrc/chat/messenger.c | 20++++++++++++++++++++
Msrc/event.c | 21+++++++++++++++++++++
Msrc/event.h | 26++++++++++++++++++++++++++
Msrc/ui/discourse.c | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Asrc/ui/discourse_panel.c | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/ui/discourse_panel.h | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/ui/meson.build | 1+
8 files changed, 308 insertions(+), 20 deletions(-)

diff --git a/resources/ui.gresource.xml b/resources/ui.gresource.xml @@ -11,6 +11,7 @@ <file compressed="true">ui/contact_info.ui</file> <file compressed="true">ui/contacts.ui</file> <file compressed="true">ui/delete_messages.ui</file> + <file compressed="true">ui/discourse_panel.ui</file> <file compressed="true">ui/discourse.ui</file> <file compressed="true">ui/files.ui</file> <file compressed="true">ui/file_entry.ui</file> diff --git a/src/chat/messenger.c b/src/chat/messenger.c @@ -213,6 +213,26 @@ _chat_messenger_message(void *cls, application_call_event(app, event_update_attributes); break; } + case GNUNET_CHAT_KIND_DISCOURSE: + { + application_call_message_event( + app, + event_discourse, + context, + message + ); + break; + } + case GNUNET_CHAT_KIND_DATA: + { + application_call_message_event( + app, + event_discourse_data, + context, + message + ); + break; + } default: break; } diff --git a/src/event.c b/src/event.c @@ -1012,3 +1012,24 @@ event_update_attributes(MESSENGER_Application *app) app ); } + +void +event_discourse(MESSENGER_Application *app, + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *msg) +{ + g_assert((app) && (context) && (msg)); + + if (context == app->ui.discourse.context) + ui_discourse_window_update(&(app->ui.discourse), context); +} + +void +event_discourse_data(MESSENGER_Application *app, + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *msg) +{ + g_assert((app) && (context) && (msg)); + + // TODO +} diff --git a/src/event.h b/src/event.h @@ -184,4 +184,30 @@ event_tag_message(MESSENGER_Application *app, void event_update_attributes(MESSENGER_Application *app); +/** + * Event for the UI to be called whenever a discourse + * message gets received in a given context. + * + * @param app Messenger application + * @param context Chat context + * @param msg Discourse message + */ +void +event_discourse(MESSENGER_Application *app, + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *msg); + +/** + * Event for the UI to be called whenever a data + * message gets received in a given context. + * + * @param app Messenger application + * @param context Chat context + * @param msg Data message + */ +void +event_discourse_data(MESSENGER_Application *app, + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *msg); + #endif /* EVENT_H_ */ diff --git a/src/ui/discourse.c b/src/ui/discourse.c @@ -29,6 +29,7 @@ #include <gnunet/gnunet_time_lib.h> #include "account_entry.h" +#include "discourse_panel.h" #include "../application.h" #include "../ui.h" @@ -110,10 +111,7 @@ handle_call_button_click(UNUSED GtkButton *button, if (!(handle->context)) return; - const gboolean calling = ( - (handle->voice_discourse) && - (GNUNET_YES == GNUNET_CHAT_discourse_is_open(handle->voice_discourse)) - ); + const gboolean calling = (handle->voice_discourse? TRUE : FALSE); struct GNUNET_ShortHashCode voice_id; memset(&voice_id, 0, sizeof(voice_id)); @@ -299,29 +297,53 @@ ui_discourse_window_init(MESSENGER_Application *app, gtk_widget_show_all(GTK_WIDGET(handle->window)); } +struct IterateDiscourseClosure { + MESSENGER_Application *app; + GtkContainer *container; +}; + static enum GNUNET_GenericReturnValue iterate_ui_discourse_update_discourse_members(void *cls, const struct GNUNET_CHAT_Discourse *discourse, struct GNUNET_CHAT_Contact *contact) { - UI_DISCOURSE_Handle *handle = (UI_DISCOURSE_Handle*) cls; + struct IterateDiscourseClosure *closure = ( + (struct IterateDiscourseClosure*) cls + ); + + GtkFlowBox *flowbox = GTK_FLOW_BOX(closure->container); + UI_DISCOURSE_PANEL_Handle* panel = ui_discourse_panel_new(closure->app); + + ui_discourse_panel_set_contact(panel, contact); + + gtk_flow_box_insert(flowbox, panel->panel_box, -1); + + GtkFlowBoxChild *child = GTK_FLOW_BOX_CHILD( + gtk_widget_get_parent(panel->panel_box) + ); - printf("%s\n", GNUNET_CHAT_contact_get_name(contact)); + g_object_set_qdata(G_OBJECT(child), closure->app->quarks.data, contact); + g_object_set_qdata_full( + G_OBJECT(child), + closure->app->quarks.ui, + panel, + (GDestroyNotify) ui_discourse_panel_delete + ); return GNUNET_YES; } static enum GNUNET_GenericReturnValue iterate_ui_discourse_update_context_discourses(void *cls, - UNUSED struct GNUNET_CHAT_Context *context, + struct GNUNET_CHAT_Context *context, struct GNUNET_CHAT_Discourse *discourse) { - UI_DISCOURSE_Handle *handle = (UI_DISCOURSE_Handle*) cls; + g_assert((cls) && (context) && (discourse)); GNUNET_CHAT_discourse_iterate_contacts( discourse, iterate_ui_discourse_update_discourse_members, - handle + cls ); return GNUNET_YES; @@ -332,28 +354,45 @@ _discourse_update_members(UI_DISCOURSE_Handle *handle) { g_assert(handle); + GList* children = gtk_container_get_children( + GTK_CONTAINER(handle->members_flowbox) + ); + + GList *item = children; + while ((item) && (item->next)) { + GtkWidget *widget = GTK_WIDGET(item->data); + item = item->next; + + gtk_container_remove( + GTK_CONTAINER(handle->members_flowbox), + widget + ); + } + + if (children) + g_list_free(children); + if (!(handle->context)) return; + struct IterateDiscourseClosure closure; + closure.app = handle->app; + closure.container = GTK_CONTAINER(handle->members_flowbox); + GNUNET_CHAT_context_iterate_discourses( handle->context, iterate_ui_discourse_update_context_discourses, - handle + &closure ); } -struct IterateChatClosure { - MESSENGER_Application *app; - GtkContainer *container; -}; - static enum GNUNET_GenericReturnValue iterate_ui_discourse_update_group_contacts(void *cls, UNUSED const struct GNUNET_CHAT_Group *group, struct GNUNET_CHAT_Contact *contact) { - struct IterateChatClosure *closure = ( - (struct IterateChatClosure*) cls + struct IterateDiscourseClosure *closure = ( + (struct IterateDiscourseClosure*) cls ); GtkListBox *listbox = GTK_LIST_BOX(closure->container); @@ -404,7 +443,7 @@ _discourse_update_contacts(UI_DISCOURSE_Handle *handle, if (group) { - struct IterateChatClosure closure; + struct IterateDiscourseClosure closure; closure.app = handle->app; closure.container = GTK_CONTAINER(handle->contacts_listbox); @@ -430,8 +469,6 @@ ui_discourse_window_update(UI_DISCOURSE_Handle *handle, if (handle->context) { // TODO - - } handle->context = context; diff --git a/src/ui/discourse_panel.c b/src/ui/discourse_panel.c @@ -0,0 +1,101 @@ +/* + This file is part of GNUnet. + Copyright (C) 2024 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet 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 + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/* + * @author Tobias Frisch + * @file ui/discourse_panel.c + */ + +#include "discourse_panel.h" + +#include "../contact.h" +#include "../ui.h" + +UI_DISCOURSE_PANEL_Handle* +ui_discourse_panel_new(MESSENGER_Application *app) +{ + g_assert(app); + + UI_DISCOURSE_PANEL_Handle* handle = g_malloc(sizeof(UI_DISCOURSE_PANEL_Handle)); + + handle->contact = NULL; + + handle->builder = ui_builder_from_resource( + application_get_resource_path(app, "ui/discourse_panel.ui") + ); + + handle->panel_box = GTK_WIDGET( + gtk_builder_get_object(handle->builder, "panel_box") + ); + + handle->panel_stack = GTK_STACK( + gtk_builder_get_object(handle->builder, "panel_stack") + ); + + handle->avatar_box = GTK_WIDGET( + gtk_builder_get_object(handle->builder, "avatar_box") + ); + + handle->panel_avatar = HDY_AVATAR( + gtk_builder_get_object(handle->builder, "panel_avatar") + ); + + handle->panel_label = GTK_LABEL( + gtk_builder_get_object(handle->builder, "panel_label") + ); + + handle->video_drawing_area = GTK_DRAWING_AREA( + gtk_builder_get_object(handle->builder, "video_drawing_area") + ); + + return handle; +} + +void +ui_discourse_panel_set_contact(UI_DISCOURSE_PANEL_Handle* handle, + const struct GNUNET_CHAT_Contact *contact) +{ + g_assert(handle); + + if (handle->contact) + { + contact_remove_name_avatar_from_info(handle->contact, handle->panel_avatar); + contact_remove_name_label_from_info(handle->contact, handle->panel_label); + } + + if (contact) + { + contact_add_name_avatar_to_info(contact, handle->panel_avatar); + contact_add_name_label_to_info(contact, handle->panel_label); + } + + handle->contact = contact; +} + +void +ui_discourse_panel_delete(UI_DISCOURSE_PANEL_Handle *handle) +{ + g_assert(handle); + + ui_discourse_panel_set_contact(handle, NULL); + + g_object_unref(handle->builder); + + g_free(handle); +} diff --git a/src/ui/discourse_panel.h b/src/ui/discourse_panel.h @@ -0,0 +1,81 @@ +/* + This file is part of GNUnet. + Copyright (C) 2024 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet 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 + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/* + * @author Tobias Frisch + * @file ui/discourse_panel.h + */ + +#ifndef UI_DISCOURSE_PANEL_H_ +#define UI_DISCOURSE_PANEL_H_ + +#include "messenger.h" + +#include <gnunet/gnunet_chat_lib.h> + +typedef struct UI_DISCOURSE_PANEL_Handle +{ + const struct GNUNET_CHAT_Contact *contact; + + GtkBuilder *builder; + + GtkWidget *panel_box; + + GtkStack *panel_stack; + GtkWidget *avatar_box; + + HdyAvatar *panel_avatar; + GtkLabel *panel_label; + + GtkDrawingArea *video_drawing_area; +} UI_DISCOURSE_PANEL_Handle; + +/** + * Allocates and creates a new discourse panel + * handle to visualize a contact in a discourse + * a given messenger application. + * + * @param app Messenger application + * @return New discourse panel handle + */ +UI_DISCOURSE_PANEL_Handle* +ui_discourse_panel_new(MESSENGER_Application *app); + +/** + * Sets the content of the given discourse panel + * handle respectively to visually represent a + * selected chat contact. + * + * @param handle Discourse panel handle + * @param contact Chat contact + */ +void +ui_discourse_panel_set_contact(UI_DISCOURSE_PANEL_Handle* handle, + const struct GNUNET_CHAT_Contact *contact); + +/** + * Frees its resources and destroys a given + * discourse panel handle. + * + * @param handle Discourse panel handle + */ +void +ui_discourse_panel_delete(UI_DISCOURSE_PANEL_Handle *handle); + +#endif /* UI_DISCOURSE_PANEL_H_ */ diff --git a/src/ui/meson.build b/src/ui/meson.build @@ -29,6 +29,7 @@ messenger_gtk_ui_sources = files([ 'contact_info.c', 'contact_info.h', 'contacts.c', 'contacts.h', 'delete_messages.c', 'delete_messages.h', + 'discourse_panel.c', 'discourse_panel.h', 'discourse.c', 'discourse.h', 'files.c', 'files.h', 'file_entry.c', 'file_entry.h',