messenger-gtk

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

commit 021d02a977a65abd69f293eaa14e0abddd44b90d
parent a15809e28bf2076683494cebf564d1622b4ca4b4
Author: Jacki <jacki@thejackimonster.de>
Date:   Sat,  6 Jan 2024 02:49:51 +0100

Implement emoji search in picker

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

Diffstat:
Mmeson.build | 1+
Msrc/ui/picker.c | 272++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
2 files changed, 203 insertions(+), 70 deletions(-)

diff --git a/meson.build b/meson.build @@ -42,6 +42,7 @@ messenger_gtk_deps = [ dependency('gstreamer-1.0'), dependency('libnotify'), dependency('libqrencode'), + declare_dependency(link_args: '-lunistring'), ] subdir('resources') diff --git a/src/ui/picker.c b/src/ui/picker.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2021 GNUnet e.V. + Copyright (C) 2021--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 @@ -28,10 +28,11 @@ #include <emoji.h> #include <glib-2.0/glib.h> +#include <uniname.h> 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); @@ -44,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; @@ -83,8 +84,132 @@ _add_emoji_buttons(GtkFlowBox *flow_box, } static void +_filter_emoji_buttons(GtkWidget* widget, + gpointer user_data) +{ + GtkSearchEntry *entry = GTK_SEARCH_ENTRY(user_data); + + const gchar *filter = gtk_entry_get_text(GTK_ENTRY(entry)); + + GList *list = gtk_container_get_children(GTK_CONTAINER(widget)); + + if (!list) + return; + + GtkButton *emoji_button = GTK_BUTTON(list->data); + + list = gtk_container_get_children(GTK_CONTAINER(emoji_button)); + + if (!list) + return; + + GtkLabel *label = GTK_LABEL(list->data); + + const gchar *text = gtk_label_get_text(label); + + if (!text) + return; + + gunichar *characters; + glong items_written; + GError *error; + + characters = g_utf8_to_ucs4 ( + text, + strlen(text), + NULL, + &items_written, + &error + ); + + if (!characters) + { + fprintf(stderr, "ERROR: %s\n", error->message); + g_error_free(error); + return; + } + + GString *search = g_string_new(filter); + g_string_ascii_up(search); + + gchar buffer [UNINAME_MAX]; + if (!unicode_character_name(*characters, buffer)) + goto skip_emoji; + + gtk_widget_set_visible( + widget, + g_strrstr(buffer, search->str)? TRUE : FALSE + ); + +skip_emoji: + g_string_free(search, TRUE); + g_free(characters); +} + +static void +handle_emoji_search_entry_search_changed(GtkSearchEntry *entry, + gpointer user_data) +{ + UI_PICKER_Handle *handle = (UI_PICKER_Handle*) user_data; + + gtk_container_foreach( + GTK_CONTAINER(handle->recent_flow_box), + _filter_emoji_buttons, + entry + ); + + gtk_container_foreach( + GTK_CONTAINER(handle->people_flow_box), + _filter_emoji_buttons, + entry + ); + + gtk_container_foreach( + GTK_CONTAINER(handle->nature_flow_box), + _filter_emoji_buttons, + entry + ); + + gtk_container_foreach( + GTK_CONTAINER(handle->food_flow_box), + _filter_emoji_buttons, + entry + ); + + gtk_container_foreach( + GTK_CONTAINER(handle->activities_flow_box), + _filter_emoji_buttons, + entry + ); + + gtk_container_foreach( + GTK_CONTAINER(handle->travel_flow_box), + _filter_emoji_buttons, + entry + ); + + gtk_container_foreach( + GTK_CONTAINER(handle->objects_flow_box), + _filter_emoji_buttons, + entry + ); + + gtk_container_foreach( + GTK_CONTAINER(handle->symbols_flow_box), + _filter_emoji_buttons, + entry + ); + + gtk_container_foreach( + GTK_CONTAINER(handle->flags_flow_box), + _filter_emoji_buttons, + entry + ); +} + +static void handle_search_button_click(UNUSED GtkButton *button, - gpointer user_data) + gpointer user_data) { UI_PICKER_Handle *handle = (UI_PICKER_Handle*) user_data; @@ -97,14 +222,14 @@ handle_search_button_click(UNUSED GtkButton *button, if (search_bar) hdy_search_bar_set_search_mode( - search_bar, - !hdy_search_bar_get_search_mode(search_bar) + search_bar, + !hdy_search_bar_get_search_mode(search_bar) ); } static void handle_settings_button_click(UNUSED GtkButton *button, - gpointer user_data) + gpointer user_data) { MESSENGER_Application *app = (MESSENGER_Application*) user_data; @@ -113,158 +238,165 @@ handle_settings_button_click(UNUSED GtkButton *button, UI_PICKER_Handle* ui_picker_new(MESSENGER_Application *app, - UI_CHAT_Handle *chat) + UI_CHAT_Handle *chat) { UI_PICKER_Handle *handle = g_malloc(sizeof(UI_PICKER_Handle)); handle->builder = gtk_builder_new_from_resource( - application_get_resource_path(app, "ui/picker.ui") + application_get_resource_path(app, "ui/picker.ui") ); handle->picker_box = GTK_WIDGET( - gtk_builder_get_object(handle->builder, "picker_box") + gtk_builder_get_object(handle->builder, "picker_box") ); handle->picker_stack = GTK_STACK( - gtk_builder_get_object(handle->builder, "picker_stack") + gtk_builder_get_object(handle->builder, "picker_stack") ); handle->emoji_stack = GTK_STACK( - gtk_builder_get_object(handle->builder, "emoji_stack") + gtk_builder_get_object(handle->builder, "emoji_stack") ); handle->recent_emoji_page = GTK_WIDGET( - gtk_builder_get_object(handle->builder, "recent_emoji_page") + gtk_builder_get_object(handle->builder, "recent_emoji_page") ); handle->picker_switcher_bar = HDY_VIEW_SWITCHER_BAR( - gtk_builder_get_object(handle->builder, "picker_switcher_bar") + gtk_builder_get_object(handle->builder, "picker_switcher_bar") ); handle->emoji_switcher_bar = HDY_VIEW_SWITCHER_BAR( - gtk_builder_get_object(handle->builder, "emoji_switcher_bar") + gtk_builder_get_object(handle->builder, "emoji_switcher_bar") ); handle->recent_flow_box = GTK_FLOW_BOX( - gtk_builder_get_object(handle->builder, "recent_flow_box") + gtk_builder_get_object(handle->builder, "recent_flow_box") ); handle->people_flow_box = GTK_FLOW_BOX( - gtk_builder_get_object(handle->builder, "people_flow_box") + gtk_builder_get_object(handle->builder, "people_flow_box") ); _add_emoji_buttons( - handle->people_flow_box, - chat->send_text_view, - EMOJI_SMILEYS_CHARACTER_COUNT, - emoji_smileys_characters + handle->people_flow_box, + chat->send_text_view, + EMOJI_SMILEYS_CHARACTER_COUNT, + emoji_smileys_characters ); handle->nature_flow_box = GTK_FLOW_BOX( - gtk_builder_get_object(handle->builder, "nature_flow_box") + gtk_builder_get_object(handle->builder, "nature_flow_box") ); _add_emoji_buttons( - handle->nature_flow_box, - chat->send_text_view, - EMOJI_ANIMALS_CHARACTER_COUNT, - emoji_animals_characters + handle->nature_flow_box, + chat->send_text_view, + EMOJI_ANIMALS_CHARACTER_COUNT, + emoji_animals_characters ); handle->food_flow_box = GTK_FLOW_BOX( - gtk_builder_get_object(handle->builder, "food_flow_box") + gtk_builder_get_object(handle->builder, "food_flow_box") ); _add_emoji_buttons( - handle->food_flow_box, - chat->send_text_view, - EMOJI_FOOD_CHARACTER_COUNT, - emoji_food_characters + handle->food_flow_box, + chat->send_text_view, + EMOJI_FOOD_CHARACTER_COUNT, + emoji_food_characters ); handle->activities_flow_box = GTK_FLOW_BOX( - gtk_builder_get_object(handle->builder, "activities_flow_box") + gtk_builder_get_object(handle->builder, "activities_flow_box") ); _add_emoji_buttons( - handle->activities_flow_box, - chat->send_text_view, - EMOJI_ACTIVITIES_CHARACTER_COUNT, - emoji_activities_characters + handle->activities_flow_box, + chat->send_text_view, + EMOJI_ACTIVITIES_CHARACTER_COUNT, + emoji_activities_characters ); handle->travel_flow_box = GTK_FLOW_BOX( - gtk_builder_get_object(handle->builder, "travel_flow_box") + gtk_builder_get_object(handle->builder, "travel_flow_box") ); _add_emoji_buttons( - handle->travel_flow_box, - chat->send_text_view, - EMOJI_TRAVEL_CHARACTER_COUNT, - emoji_travel_characters + handle->travel_flow_box, + chat->send_text_view, + EMOJI_TRAVEL_CHARACTER_COUNT, + emoji_travel_characters ); handle->objects_flow_box = GTK_FLOW_BOX( - gtk_builder_get_object(handle->builder, "objects_flow_box") + gtk_builder_get_object(handle->builder, "objects_flow_box") ); _add_emoji_buttons( - handle->objects_flow_box, - chat->send_text_view, - EMOJI_OBJECTS_CHARACTER_COUNT, - emoji_objects_characters + handle->objects_flow_box, + chat->send_text_view, + EMOJI_OBJECTS_CHARACTER_COUNT, + emoji_objects_characters ); handle->symbols_flow_box = GTK_FLOW_BOX( - gtk_builder_get_object(handle->builder, "symbols_flow_box") + gtk_builder_get_object(handle->builder, "symbols_flow_box") ); _add_emoji_buttons( - handle->symbols_flow_box, - chat->send_text_view, - EMOJI_SYMBOLS_CHARACTER_COUNT, - emoji_symbols_characters + handle->symbols_flow_box, + chat->send_text_view, + EMOJI_SYMBOLS_CHARACTER_COUNT, + emoji_symbols_characters ); handle->flags_flow_box = GTK_FLOW_BOX( - gtk_builder_get_object(handle->builder, "flags_flow_box") + gtk_builder_get_object(handle->builder, "flags_flow_box") ); _add_emoji_buttons( - handle->flags_flow_box, - chat->send_text_view, - EMOJI_FLAGS_CHARACTER_COUNT, - emoji_flags_characters + handle->flags_flow_box, + chat->send_text_view, + EMOJI_FLAGS_CHARACTER_COUNT, + emoji_flags_characters ); handle->emoji_search_bar = HDY_SEARCH_BAR( - gtk_builder_get_object(handle->builder, "emoji_search_bar") + gtk_builder_get_object(handle->builder, "emoji_search_bar") ); handle->emoji_search_entry = GTK_SEARCH_ENTRY( - gtk_builder_get_object(handle->builder, "emoji_search_entry") + gtk_builder_get_object(handle->builder, "emoji_search_entry") + ); + + g_signal_connect( + handle->emoji_search_entry, + "search-changed", + G_CALLBACK(handle_emoji_search_entry_search_changed), + handle ); handle->search_button = GTK_BUTTON( - gtk_builder_get_object(handle->builder, "search_button") + gtk_builder_get_object(handle->builder, "search_button") ); g_signal_connect( - handle->search_button, - "clicked", - G_CALLBACK(handle_search_button_click), - handle + handle->search_button, + "clicked", + G_CALLBACK(handle_search_button_click), + handle ); handle->settings_button = GTK_BUTTON( - gtk_builder_get_object(handle->builder, "settings_button") + gtk_builder_get_object(handle->builder, "settings_button") ); g_signal_connect( - handle->settings_button, - "clicked", - G_CALLBACK(handle_settings_button_click), - app + handle->settings_button, + "clicked", + G_CALLBACK(handle_settings_button_click), + app ); return handle;