commit 9c4c0589f3d50425bd51c830f49110a107d3c541
parent 11bef15928c414e2a26e8e4b63104dd684bf60f2
Author: Jacki <jacki@thejackimonster.de>
Date: Sun, 16 Jun 2024 01:16:24 +0200
Implement buttons switching icons on interaction
Signed-off-by: Jacki <jacki@thejackimonster.de>
Diffstat:
5 files changed, 265 insertions(+), 11 deletions(-)
diff --git a/resources/ui/discourse.ui b/resources/ui/discourse.ui
@@ -129,7 +129,7 @@ Author: Tobias Frisch
<property name="receives-default">True</property>
<property name="relief">none</property>
<child>
- <object class="GtkStack">
+ <object class="GtkStack" id="microphone_stack">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
@@ -139,8 +139,7 @@ Author: Tobias Frisch
<property name="icon-name">microphone-sensitivity-high-symbolic</property>
</object>
<packing>
- <property name="name">page0</property>
- <property name="title" translatable="yes">page0</property>
+ <property name="name">on_page</property>
</packing>
</child>
<child>
@@ -150,8 +149,7 @@ Author: Tobias Frisch
<property name="icon-name">microphone-sensitivity-muted-symbolic</property>
</object>
<packing>
- <property name="name">page1</property>
- <property name="title" translatable="yes">page1</property>
+ <property name="name">off_page</property>
<property name="position">1</property>
</packing>
</child>
@@ -248,7 +246,7 @@ audio-volume-medium-symbolic</property>
<property name="receives-default">True</property>
<property name="relief">none</property>
<child>
- <object class="GtkStack">
+ <object class="GtkStack" id="call_stack">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
@@ -258,8 +256,7 @@ audio-volume-medium-symbolic</property>
<property name="icon-name">call-start-symbolic</property>
</object>
<packing>
- <property name="name">page0</property>
- <property name="title" translatable="yes">page0</property>
+ <property name="name">start_page</property>
</packing>
</child>
<child>
@@ -269,8 +266,7 @@ audio-volume-medium-symbolic</property>
<property name="icon-name">call-stop-symbolic</property>
</object>
<packing>
- <property name="name">page1</property>
- <property name="title" translatable="yes">page1</property>
+ <property name="name">stop_page</property>
<property name="position">1</property>
</packing>
</child>
diff --git a/resources/ui/discourse_panel.ui b/resources/ui/discourse_panel.ui
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.40.0
+
+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
+
+-->
+<interface>
+ <requires lib="gtk+" version="3.24"/>
+ <requires lib="libhandy" version="1.2"/>
+ <object class="GtkBox" id="panel_box">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkStack" id="panel_stack">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkBox" id="avatar_box">
+ <property name="width-request">140</property>
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="border-width">8</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="HdyAvatar" id="panel_avatar">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="icon-name">avatar-default</property>
+ <property name="size">80</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="panel_label">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="wrap">True</property>
+ <property name="wrap-mode">word-char</property>
+ <property name="ellipsize">end</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="name">avatar_page</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="video_drawing_area">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="name">video_page</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/src/ui/chat.c b/src/ui/chat.c
@@ -25,8 +25,8 @@
#include "chat.h"
#include <gdk/gdkkeysyms.h>
-#include <gnunet/gnunet_chat_lib.h>
#include <gnunet/gnunet_common.h>
+#include <gnunet/gnunet_chat_lib.h>
#include <gnunet/gnunet_time_lib.h>
#include <stdlib.h>
diff --git a/src/ui/discourse.c b/src/ui/discourse.c
@@ -24,11 +24,18 @@
#include "discourse.h"
+#include <gnunet/gnunet_common.h>
+#include <gnunet/gnunet_chat_lib.h>
+#include <gnunet/gnunet_time_lib.h>
+
#include "account_entry.h"
#include "../application.h"
#include "../ui.h"
#include "../util.h"
+#include <gnunet/gnunet_chat_lib.h>
+#include <gnunet/gnunet_common.h>
+#include <string.h>
static void
handle_back_button_click(UNUSED GtkButton *button,
@@ -70,6 +77,64 @@ handle_details_folded(GObject* object,
}
static void
+_update_microphone_icon(UI_DISCOURSE_Handle *handle)
+{
+ g_assert(handle);
+
+ if (handle->muted)
+ gtk_stack_set_visible_child(handle->microphone_stack, handle->microphone_off_icon);
+ else
+ gtk_stack_set_visible_child(handle->microphone_stack, handle->microphone_on_icon);
+}
+
+static void
+handle_microphone_button_click(UNUSED GtkButton *button,
+ gpointer user_data)
+{
+ g_assert(user_data);
+
+ UI_DISCOURSE_Handle *handle = (UI_DISCOURSE_Handle*) user_data;
+
+ handle->muted = !(handle->muted);
+ _update_microphone_icon(handle);
+}
+
+static void
+handle_call_button_click(UNUSED GtkButton *button,
+ gpointer user_data)
+{
+ g_assert(user_data);
+
+ UI_DISCOURSE_Handle *handle = (UI_DISCOURSE_Handle*) user_data;
+
+ if (!(handle->context))
+ return;
+
+ const gboolean calling = (
+ (handle->voice_discourse) &&
+ (GNUNET_YES == GNUNET_CHAT_discourse_is_open(handle->voice_discourse))
+ );
+
+ struct GNUNET_ShortHashCode voice_id;
+ memset(&voice_id, 0, sizeof(voice_id));
+
+ if (calling)
+ {
+ GNUNET_CHAT_discourse_close(handle->voice_discourse);
+ handle->voice_discourse = NULL;
+ }
+ else
+ handle->voice_discourse = GNUNET_CHAT_context_open_discourse(
+ handle->context, &voice_id
+ );
+
+ if (handle->voice_discourse)
+ gtk_stack_set_visible_child(handle->call_stack, handle->call_stop_icon);
+ else
+ gtk_stack_set_visible_child(handle->call_stack, handle->call_start_icon);
+}
+
+static void
handle_window_destroy(UNUSED GtkWidget *window,
gpointer user_data)
{
@@ -87,6 +152,9 @@ ui_discourse_window_init(MESSENGER_Application *app,
handle->app = app;
handle->context = NULL;
+ handle->voice_discourse = NULL;
+ handle->muted = TRUE;
+
handle->parent = GTK_WINDOW(app->ui.messenger.main_window);
handle->builder = ui_builder_from_resource(
@@ -152,6 +220,13 @@ ui_discourse_window_init(MESSENGER_Application *app,
gtk_builder_get_object(handle->builder, "microphone_button")
);
+ g_signal_connect(
+ handle->microphone_button,
+ "clicked",
+ G_CALLBACK(handle_microphone_button_click),
+ handle
+ );
+
handle->camera_button = GTK_BUTTON(
gtk_builder_get_object(handle->builder, "camera_button")
);
@@ -168,6 +243,37 @@ ui_discourse_window_init(MESSENGER_Application *app,
gtk_builder_get_object(handle->builder, "call_button")
);
+ g_signal_connect(
+ handle->call_button,
+ "clicked",
+ G_CALLBACK(handle_call_button_click),
+ handle
+ );
+
+ handle->microphone_stack = GTK_STACK(
+ gtk_builder_get_object(handle->builder, "microphone_stack")
+ );
+
+ handle->microphone_on_icon = GTK_WIDGET(
+ gtk_builder_get_object(handle->builder, "microphone_on_icon")
+ );
+
+ handle->microphone_off_icon = GTK_WIDGET(
+ gtk_builder_get_object(handle->builder, "microphone_off_icon")
+ );
+
+ handle->call_stack = GTK_STACK(
+ gtk_builder_get_object(handle->builder, "call_stack")
+ );
+
+ handle->call_start_icon = GTK_WIDGET(
+ gtk_builder_get_object(handle->builder, "call_start_icon")
+ );
+
+ handle->call_stop_icon = GTK_WIDGET(
+ gtk_builder_get_object(handle->builder, "call_stop_icon")
+ );
+
handle->close_details_button = GTK_BUTTON(
gtk_builder_get_object(handle->builder, "close_details_button")
);
@@ -193,6 +299,49 @@ ui_discourse_window_init(MESSENGER_Application *app,
gtk_widget_show_all(GTK_WIDGET(handle->window));
}
+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;
+
+ printf("%s\n", GNUNET_CHAT_contact_get_name(contact));
+
+ return GNUNET_YES;
+}
+
+static enum GNUNET_GenericReturnValue
+iterate_ui_discourse_update_context_discourses(void *cls,
+ UNUSED struct GNUNET_CHAT_Context *context,
+ struct GNUNET_CHAT_Discourse *discourse)
+{
+ UI_DISCOURSE_Handle *handle = (UI_DISCOURSE_Handle*) cls;
+
+ GNUNET_CHAT_discourse_iterate_contacts(
+ discourse,
+ iterate_ui_discourse_update_discourse_members,
+ handle
+ );
+
+ return GNUNET_YES;
+}
+
+static void
+_discourse_update_members(UI_DISCOURSE_Handle *handle)
+{
+ g_assert(handle);
+
+ if (!(handle->context))
+ return;
+
+ GNUNET_CHAT_context_iterate_discourses(
+ handle->context,
+ iterate_ui_discourse_update_context_discourses,
+ handle
+ );
+}
+
struct IterateChatClosure {
MESSENGER_Application *app;
GtkContainer *container;
@@ -287,6 +436,9 @@ ui_discourse_window_update(UI_DISCOURSE_Handle *handle,
handle->context = context;
+ _update_microphone_icon(handle);
+ _discourse_update_members(handle);
+
struct GNUNET_CHAT_Group* group = GNUNET_CHAT_context_get_group(
handle->context
);
diff --git a/src/ui/discourse.h b/src/ui/discourse.h
@@ -27,6 +27,8 @@
#include "messenger.h"
+#include <gnunet/gnunet_chat_lib.h>
+
#include <glib-2.0/glib.h>
#include <gstreamer-1.0/gst/gst.h>
#include <pthread.h>
@@ -36,6 +38,10 @@ typedef struct UI_DISCOURSE_Handle
MESSENGER_Application *app;
struct GNUNET_CHAT_Context *context;
+ struct GNUNET_CHAT_Discourse *voice_discourse;
+
+ gboolean muted;
+
GtkWindow *parent;
GtkBuilder *builder;
@@ -55,6 +61,14 @@ typedef struct UI_DISCOURSE_Handle
GtkVolumeButton *speakers_button;
GtkButton *call_button;
+ GtkStack *microphone_stack;
+ GtkWidget *microphone_on_icon;
+ GtkWidget *microphone_off_icon;
+
+ GtkStack *call_stack;
+ GtkWidget *call_start_icon;
+ GtkWidget *call_stop_icon;
+
GtkButton *close_details_button;
GtkListBox *contacts_listbox;
} UI_DISCOURSE_Handle;