messenger-gtk

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

commit 89363b9edd1d54c07d22ae563104d1d8a2a3a8cd
parent e17fc4e572c37a421337362d52832aca75796182
Author: TheJackiMonster <thejackimonster@gmail.com>
Date:   Mon,  1 Nov 2021 23:55:21 +0100

Added dialog to create a new platform and connected new events

Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>

Diffstat:
MMakefile | 3++-
Mresources/css/style.css | 5+++++
Mresources/ui/message-sent.ui | 4++++
Mresources/ui/message.ui | 4++++
Aresources/ui/new_platform.ui | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/application.c | 7+++++--
Msrc/application.h | 9+++++++--
Msrc/chat/messenger.c | 32++++++++++++++++++++++++++++----
Msrc/event.c | 28++++++++++++++++++++++------
Msrc/event.h | 7++++++-
Msrc/ui/messenger.c | 21+++++++++++++++++++++
Asrc/ui/new_platform.c | 122+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/ui/new_platform.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
13 files changed, 419 insertions(+), 16 deletions(-)

diff --git a/Makefile b/Makefile @@ -9,7 +9,8 @@ SOURCES = messenger_gtk.c\ chat/messenger.c\ ui/chat_entry.c\ ui/message.c\ - ui/messenger.c + ui/messenger.c\ + ui/new_platform.c HEADERS = diff --git a/resources/css/style.css b/resources/css/style.css @@ -33,3 +33,8 @@ color: @theme_selected_fg_color; margin-left: 20px; } + +.message-content { + padding-top: 4px; +} + diff --git a/resources/ui/message-sent.ui b/resources/ui/message-sent.ui @@ -54,6 +54,7 @@ Author: Tobias Frisch <property name="visible">True</property> <property name="can-focus">False</property> <property name="orientation">vertical</property> + <property name="spacing">4</property> <child> <object class="GtkLabel" id="text_label"> <property name="visible">True</property> @@ -109,6 +110,9 @@ Author: Tobias Frisch <property name="position">1</property> </packing> </child> + <style> + <class name="message-content"/> + </style> </object> </child> <child type="label"> diff --git a/resources/ui/message.ui b/resources/ui/message.ui @@ -53,6 +53,7 @@ Author: Tobias Frisch <property name="visible">True</property> <property name="can-focus">False</property> <property name="orientation">vertical</property> + <property name="spacing">4</property> <child> <object class="GtkLabel" id="text_label"> <property name="visible">True</property> @@ -107,6 +108,9 @@ Author: Tobias Frisch <property name="position">1</property> </packing> </child> + <style> + <class name="message-content"/> + </style> </object> </child> <child type="label"> diff --git a/resources/ui/new_platform.ui b/resources/ui/new_platform.ui @@ -0,0 +1,146 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.38.2 + +Copyright (C) 2021 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 + +--> +<interface> + <requires lib="gtk+" version="3.24"/> + <requires lib="libhandy" version="1.2"/> + <object class="GtkDialog" id="platform_dialog"> + <property name="can-focus">False</property> + <property name="window-position">center-on-parent</property> + <property name="type-hint">dialog</property> + <child internal-child="vbox"> + <object class="GtkBox"> + <property name="can-focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">2</property> + <child internal-child="action_area"> + <object class="GtkButtonBox"> + <property name="can-focus">False</property> + <property name="layout-style">end</property> + <child> + <object class="GtkButton" id="cancel_button"> + <property name="label" translatable="yes">Cancel</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="confirm_button"> + <property name="label" translatable="yes">Confirm</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="halign">center</property> + <property name="margin-start">8</property> + <property name="margin-end">8</property> + <property name="margin-top">8</property> + <property name="margin-bottom">8</property> + <property name="orientation">vertical</property> + <property name="spacing">4</property> + <child> + <object class="HdyAvatar" id="platform_avatar"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="halign">center</property> + <property name="margin-top">8</property> + <property name="margin-bottom">8</property> + <property name="icon-name">network-wired-symbolic</property> + <property name="size">128</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes">Platform:</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="platform_entry"> + <property name="width-request">250</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkFileChooserButton" id="platform_avatar_file"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="title" translatable="yes"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">3</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> +</interface> diff --git a/src/application.c b/src/application.c @@ -147,6 +147,7 @@ typedef struct MESSENGER_ApplicationEventCall { MESSENGER_Application *app; MESSENGER_ApplicationEvent event; + void *cls; } MESSENGER_ApplicationEventCall; static gboolean @@ -155,7 +156,7 @@ _application_event_call(gpointer user_data) MESSENGER_ApplicationEventCall *call; call = (MESSENGER_ApplicationEventCall*) user_data; - call->event(call->app); + call->event(call->app, call->cls); GNUNET_free(call); return FALSE; @@ -163,7 +164,8 @@ _application_event_call(gpointer user_data) void application_call_event(MESSENGER_Application *app, - MESSENGER_ApplicationEvent event) + MESSENGER_ApplicationEvent event, + void *cls) { MESSENGER_ApplicationEventCall *call; @@ -173,6 +175,7 @@ application_call_event(MESSENGER_Application *app, call->app = app; call->event = event; + call->cls = cls; g_idle_add(_application_event_call, call); } diff --git a/src/application.h b/src/application.h @@ -30,6 +30,7 @@ #include "chat/messenger.h" #include "ui/messenger.h" +#include "ui/new_platform.h" #include "util.h" @@ -61,6 +62,8 @@ typedef struct MESSENGER_Application gboolean mobile; UI_MESSENGER_Handle messenger; + + UI_NEW_PLATFORM_Handle new_platform; } ui; } MESSENGER_Application; @@ -72,11 +75,13 @@ application_init(MESSENGER_Application *app, void application_run(MESSENGER_Application *app); -typedef void (*MESSENGER_ApplicationEvent) (MESSENGER_Application *app); +typedef void (*MESSENGER_ApplicationEvent) (MESSENGER_Application *app, + void *cls); void application_call_event(MESSENGER_Application *app, - MESSENGER_ApplicationEvent event); + MESSENGER_ApplicationEvent event, + void *cls); void application_exit(MESSENGER_Application *app, diff --git a/src/chat/messenger.c b/src/chat/messenger.c @@ -57,10 +57,34 @@ _chat_messenger_message(void *cls, { MESSENGER_Application *app = (MESSENGER_Application*) cls; - if (GNUNET_CHAT_KIND_LOGIN == GNUNET_CHAT_message_get_kind(message)) - application_call_event(app, event_update_profile); - else if (GNUNET_CHAT_KIND_TEXT == GNUNET_CHAT_message_get_kind(message)) - printf("%s\n", GNUNET_CHAT_message_get_text(message)); + const enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message); + const struct GNUNET_CHAT_Contact* sender = GNUNET_CHAT_message_get_sender(message); + + struct GNUNET_TIME_Absolute time = GNUNET_CHAT_message_get_timestamp(message); + + printf("- %d, %lu", kind, time.abs_value_us); + + if (sender) + printf(", %s\n", GNUNET_CHAT_contact_get_name(sender)); + else + printf("\n"); + + switch (kind) + { + case GNUNET_CHAT_KIND_LOGIN: + application_call_event(app, event_update_profile, NULL); + break; + case GNUNET_CHAT_KIND_TEXT: + printf("text: %s\n", GNUNET_CHAT_message_get_text(message)); + break; + case GNUNET_CHAT_KIND_JOIN: + if (GNUNET_YES == GNUNET_CHAT_message_is_sent(message)) + application_call_event(app, event_update_chats, context); + + break; + default: + break; + } return GNUNET_YES; } diff --git a/src/event.c b/src/event.c @@ -73,7 +73,8 @@ _clear_each_widget(GtkWidget *widget, } void -event_update_profile(MESSENGER_Application *app) +event_update_profile(MESSENGER_Application *app, + UNUSED void *cls) { UI_MESSENGER_Handle *ui = &(app->ui.messenger); CHAT_MESSENGER_Handle *chat = &(app->chat.messenger); @@ -95,13 +96,28 @@ event_update_profile(MESSENGER_Application *app) GNUNET_CHAT_iterate_contacts(chat->handle, _iterate_profile_contacts, app); GNUNET_CHAT_iterate_groups(chat->handle, _iterate_profile_groups, app); - UI_CHAT_ENTRY_Handle *entry = ui_chat_entry_new(); - gtk_container_add(GTK_CONTAINER(ui->chats_listbox), entry->entry_box); - g_free(entry); - for (int i = 0; i < 8; i++) { UI_MESSAGE_Handle *message = ui_message_new(app, i % 2 == 0); gtk_container_add(GTK_CONTAINER(ui->messages_listbox), message->message_box); - g_free(message); + g_free(message); // TODO: this is just a test! } } + +void +event_update_chats(MESSENGER_Application *app, + void *cls) +{ + struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) cls; + + if (GNUNET_CHAT_context_get_user_pointer(context)) + return; + + UI_MESSENGER_Handle *ui = &(app->ui.messenger); + + UI_CHAT_ENTRY_Handle *entry = ui_chat_entry_new(); + gtk_container_add(GTK_CONTAINER(ui->chats_listbox), entry->entry_box); + g_free(entry); // TODO: free already? + + // TODO: put something better here to attach it! + GNUNET_CHAT_context_set_user_pointer(context, ui); +} diff --git a/src/event.h b/src/event.h @@ -28,6 +28,11 @@ #include "application.h" void -event_update_profile(MESSENGER_Application *app); +event_update_profile(MESSENGER_Application *app, + void *cls); + +void +event_update_chats(MESSENGER_Application *app, + void *cls); #endif /* EVENT_H_ */ diff --git a/src/ui/messenger.c b/src/ui/messenger.c @@ -24,6 +24,7 @@ #include "messenger.h" +#include "new_platform.h" #include "../application.h" static void @@ -53,6 +54,19 @@ handle_account_details_button_click(UNUSED GtkButton* button, } static void +handle_new_platform_button_click(UNUSED GtkButton* button, + gpointer user_data) +{ + MESSENGER_Application *app = (MESSENGER_Application*) user_data; + + hdy_flap_set_reveal_flap(HDY_FLAP(app->ui.messenger.flap_user_details), FALSE); + + ui_new_platform_dialog_init(app, &(app->ui.new_platform)); + + gtk_widget_show(GTK_WIDGET(app->ui.new_platform.platform_dialog)); +} + +static void handle_chats_listbox_row_activated(UNUSED GtkListBox* listbox, UNUSED GtkListBoxRow* row, gpointer user_data) @@ -215,6 +229,13 @@ ui_messenger_init(MESSENGER_Application *app, gtk_builder_get_object(builder, "new_platform_button") ); + g_signal_connect( + handle->new_platform_button, + "clicked", + G_CALLBACK(handle_new_platform_button_click), + app + ); + handle->contacts_button = GTK_BUTTON( gtk_builder_get_object(builder, "contacts_button") ); diff --git a/src/ui/new_platform.c b/src/ui/new_platform.c @@ -0,0 +1,122 @@ +/* + This file is part of GNUnet. + Copyright (C) 2021 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/new_platform.h + */ + +#include "new_platform.h" + +#include "../application.h" + +static void +handle_platform_entry_changed(GtkEditable *editable, + gpointer user_data) +{ + HdyAvatar *avatar = HDY_AVATAR(user_data); + GtkEntry *entry = GTK_ENTRY(editable); + + hdy_avatar_set_text(avatar, gtk_entry_get_text(entry)); +} + +static void +handle_cancel_button_click(UNUSED GtkButton *button, + gpointer user_data) +{ + GtkDialog *dialog = GTK_DIALOG(user_data); + gtk_window_close(GTK_WINDOW(dialog)); +} + +static void +handle_confirm_button_click(UNUSED GtkButton *button, + gpointer user_data) +{ + MESSENGER_Application *app = (MESSENGER_Application*) user_data; + + const char *topic = gtk_entry_get_text(app->ui.new_platform.platform_entry); + + GNUNET_CHAT_group_create(app->chat.messenger.handle, topic); + + gtk_window_close(GTK_WINDOW(app->ui.new_platform.platform_dialog)); +} + +void +ui_new_platform_dialog_init(MESSENGER_Application *app, + UI_NEW_PLATFORM_Handle *handle) +{ + GtkBuilder* builder = gtk_builder_new_from_file("resources/ui/new_platform.ui"); + + handle->platform_dialog = GTK_DIALOG( + gtk_builder_get_object(builder, "platform_dialog") + ); + + gtk_window_set_title( + GTK_WINDOW(handle->platform_dialog), + "New Platform" + ); + + gtk_window_set_transient_for( + GTK_WINDOW(handle->platform_dialog), + GTK_WINDOW(app->ui.messenger.main_window) + ); + + gtk_window_set_modal(GTK_WINDOW(handle->platform_dialog), TRUE); + + handle->platform_avatar = HDY_AVATAR( + gtk_builder_get_object(builder, "platform_avatar") + ); + + handle->platform_avatar_file = GTK_FILE_CHOOSER_BUTTON( + gtk_builder_get_object(builder, "platform_avatar_file") + ); + + handle->platform_entry = GTK_ENTRY( + gtk_builder_get_object(builder, "platform_entry") + ); + + g_signal_connect( + handle->platform_entry, + "changed", + G_CALLBACK(handle_platform_entry_changed), + handle->platform_avatar + ); + + handle->cancel_button = GTK_BUTTON( + gtk_builder_get_object(builder, "cancel_button") + ); + + g_signal_connect( + handle->cancel_button, + "clicked", + G_CALLBACK(handle_cancel_button_click), + handle->platform_dialog + ); + + handle->confirm_button = GTK_BUTTON( + gtk_builder_get_object(builder, "confirm_button") + ); + + g_signal_connect( + handle->confirm_button, + "clicked", + G_CALLBACK(handle_confirm_button_click), + app + ); +} diff --git a/src/ui/new_platform.h b/src/ui/new_platform.h @@ -0,0 +1,47 @@ +/* + This file is part of GNUnet. + Copyright (C) 2021 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/new_platform.h + */ + +#ifndef UI_NEW_PLATFORM_H_ +#define UI_NEW_PLATFORM_H_ + +#include "messenger.h" + +typedef struct UI_NEW_PLATFORM_Handle +{ + GtkDialog* platform_dialog; + + HdyAvatar* platform_avatar; + GtkFileChooserButton* platform_avatar_file; + + GtkEntry* platform_entry; + + GtkButton* cancel_button; + GtkButton* confirm_button; +} UI_NEW_PLATFORM_Handle; + +void +ui_new_platform_dialog_init(MESSENGER_Application *app, + UI_NEW_PLATFORM_Handle *handle); + +#endif /* UI_NEW_PLATFORM_H_ */