diff --git a/src/combined_emoji.vala b/src/combined_emoji.vala index 8d62b26..3de453b 100644 --- a/src/combined_emoji.vala +++ b/src/combined_emoji.vala @@ -1,6 +1,6 @@ /* combined_emojji.vala * - * Copyright 2023-2024 José Hunter + * Copyright 2023-2025 José Hunter * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,21 +31,23 @@ namespace Mingle { public async CombinedEmoji (EmojiCombination combination_struct, Gtk.RevealerTransitionType transition, out bool image_loaded) { try { this.combined_emoji = combination_struct; + this.tooltip_text = prettify_combined_alt_name (this.combined_emoji.alt); this.add_css_class ("flat"); + // Fetch the image asynchronously var input_stream = yield get_input_stream (combined_emoji.gstatic_url); - var pixbuf = yield new Gdk.Pixbuf.from_stream_async (input_stream, null); + // Textures _texture = Gdk.Texture.for_pixbuf (pixbuf); int width = pixbuf.get_width (); int height = pixbuf.get_height (); int scaled_width = width / 4; int scaled_height = height / 4; pixbuf = pixbuf.scale_simple (scaled_width, scaled_height, Gdk.InterpType.BILINEAR); - _scaled_texture = Gdk.Texture.for_pixbuf (pixbuf); + // Widgets var overlay = new Gtk.Overlay () { child = new Gtk.Picture () { width_request = 100, @@ -73,7 +75,7 @@ namespace Mingle { overlay.add_overlay (revealer); image_loaded = true; } catch (GLib.Error error) { - // stderr.printf (error.message); + warning (error.message); image_loaded = false; } @@ -113,5 +115,24 @@ namespace Mingle { clipboard.set_texture (_texture); } } + + public string prettify_combined_alt_name(string alt_name) { + // Replace underscores with spaces and hyphens with ' + ' + string parsed_name = alt_name.replace("_", " ").replace("-", " + "); + + // Split into words + var words = parsed_name.down().split(" "); + string pretty_name = ""; + + foreach (var word in words) { + if (word.length > 0 && word != "+") { // Skip single '+' + pretty_name += word[0].to_string().up() + word.substring(1) + " "; + } else if (word == "+") { + pretty_name += "+ "; // Add '+' with a space + } + } + + return pretty_name.strip(); // Remove any trailing space + } } -} \ No newline at end of file +} diff --git a/src/emoji_label.vala b/src/emoji_label.vala index 3fd5175..bed288e 100644 --- a/src/emoji_label.vala +++ b/src/emoji_label.vala @@ -1,6 +1,6 @@ /* emoji_label.vala * - * Copyright 2023-2024 José Hunter + * Copyright 2023-2025 José Hunter * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -69,4 +69,4 @@ namespace Mingle { return pretty_name; } } -} \ No newline at end of file +} diff --git a/src/gtk/window.blp b/src/gtk/window.blp index a22e392..369501d 100644 --- a/src/gtk/window.blp +++ b/src/gtk/window.blp @@ -16,57 +16,63 @@ template $MingleWindow: Adw.ApplicationWindow { } } - content: Gtk.Stack window_stack { - transition-type: crossfade; - - Gtk.Box { - halign : center; - valign: center; - orientation: vertical; - Adw.Spinner loading_spinner { - visible: true; - width-request: 64; - height-request: 64; - margin-bottom: 12; + content: Adw.ToolbarView toolbar_view { + top-bar-style: flat; + + [top] + Adw.HeaderBar header_bar { + [end] + MenuButton { + primary: true; + icon-name: "open-menu-symbolic"; + tooltip-text: _("Menu"); + + popover: Gtk.PopoverMenu popover_menu { + menu-model: primary_menu; + }; + } + + [start] + Button randomize_button { + icon-name: "dice3-symbolic"; + tooltip-text: _("Randomize"); + clicked => $select_random(); + visible: false; } - Gtk.Label { - label: "Loading Emojis..."; - styles ["title-1"] + + [start] + ToggleButton search_button { + icon-name: "edit-find-symbolic"; + toggled => $toggle_search(); + visible: false; } } - Adw.ToastOverlay toast_overlay { - Adw.ToolbarView toolbar { - top-bar-style: raised; - - [top] - Adw.HeaderBar header_bar { - [end] - MenuButton { - primary: true; - icon-name: "open-menu-symbolic"; - tooltip-text: _("Menu"); - - popover: Gtk.PopoverMenu popover_menu { - menu-model: primary_menu; - }; - } - [start] - Button { - icon-name: "dice3-symbolic"; - tooltip-text: _("Randomize"); - clicked => $select_random(); - } + content: Gtk.Stack window_stack { + transition-type: crossfade; - [start] - Button { - icon-name: "edit-find-symbolic"; - clicked => $search(); - visible: bind search_bar.search-mode-enabled inverted; - } + // Loading State + Gtk.Box { + halign: center; + valign: center; + orientation: vertical; + + Adw.Spinner loading_spinner { + visible: true; + width-request: 64; + height-request: 64; + margin-bottom: 12; + } + + Gtk.Label { + label: "Loading Emojis..."; + styles ["title-1"] } + } - content: Box content_box { + // Main Content State + Adw.ToastOverlay toast_overlay { + Box content_box { orientation: vertical; SearchBar search_bar { @@ -89,7 +95,6 @@ template $MingleWindow: Adw.ApplicationWindow { hscrollbar-policy: never; hexpand: true; has-frame: false; - window-placement: top_right; FlowBox left_emojis_flow_box { margin-start: 6; @@ -162,12 +167,13 @@ template $MingleWindow: Adw.ApplicationWindow { } } } - }; + } } - } + }; }; } +// Menu Definitions menu primary_menu { section { item { diff --git a/src/window.vala b/src/window.vala index f52f7aa..d09cab1 100644 --- a/src/window.vala +++ b/src/window.vala @@ -1,6 +1,6 @@ /* window.vala * - * Copyright 2023-2024 José Hunter + * Copyright 2023-2025 José Hunter * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,14 +28,16 @@ namespace Mingle { [GtkChild] private unowned Gtk.FlowBox right_emojis_flow_box; [GtkChild] private unowned Gtk.FlowBox combined_emojis_flow_box; [GtkChild] private unowned Gtk.ScrolledWindow combined_scrolled_window; + [GtkChild] private unowned Gtk.ScrolledWindow left_scrolled_window; + [GtkChild] private unowned Gtk.ScrolledWindow right_scrolled_window; [GtkChild] private unowned Adw.ToastOverlay toast_overlay; [GtkChild] private unowned Gtk.PopoverMenu popover_menu; - [GtkChild] private unowned Adw.ToolbarView toolbar; + [GtkChild] private unowned Adw.ToolbarView toolbar_view; + [GtkChild] private unowned Gtk.Button randomize_button; + [GtkChild] private unowned Gtk.ToggleButton search_button; [GtkChild] private unowned Adw.Breakpoint breakpoint; [GtkChild] private unowned Gtk.SearchBar search_bar; [GtkChild] private unowned Gtk.SearchEntry search_entry; - [GtkChild] private unowned Gtk.ScrolledWindow left_scrolled_window; - [GtkChild] private unowned Gtk.ScrolledWindow right_scrolled_window; private GLib.Binding? scroll_binding; // Class variables @@ -44,6 +46,7 @@ namespace Mingle { private EmojiDataManager emoji_manager; private EmojiLabel left_emoji; private EmojiLabel right_emoji; + // Codepoints private string prev_left_emoji; private string prev_right_emoji; @@ -71,7 +74,6 @@ namespace Mingle { GLib.Object (application : app); // base constructor popover_menu.add_child (style_switcher, "style-switcher"); // Add style switcher to popover menu setup_breakpoints (); - apply_toolbar_style (); update_transition_type (); bind_scroll_adjustments (); @@ -85,10 +87,12 @@ namespace Mingle { }); search_bar.notify["search-mode-enabled"].connect (() => { + search_button.active = search_bar.search_mode_enabled; if (!search_bar.search_mode_enabled) { bind_scroll_adjustments (); } else { unbind_scroll_adjustments (); + toggle_search (); } }); @@ -97,10 +101,12 @@ namespace Mingle { start_setup_thread (); }); } - private async void setup_emoji_manager () { - emoji_manager = yield new EmojiDataManager (); - setup_emoji_flow_boxes (); - } + + private async void setup_emoji_manager () { + emoji_manager = yield new EmojiDataManager (); + setup_emoji_flow_boxes (); + apply_toolbar_view_style (); + } private void start_setup_thread () { if (!Thread.supported ()) { @@ -144,7 +150,7 @@ namespace Mingle { private void handle_pref_change (string key) { switch (key) { case "headerbar-style": - apply_toolbar_style (); + apply_toolbar_view_style (); break; case "transition-type": update_transition_type (); @@ -332,8 +338,13 @@ namespace Mingle { } [GtkCallback] - private void search () { - search_bar.search_mode_enabled = true; + private void toggle_search () { + // Check the state of the search button and update the search mode + if (search_button.active) { + search_bar.search_mode_enabled = true; + } else { + search_bar.search_mode_enabled = false; + } } private void create_and_show_toast (string message, int duration) { @@ -435,12 +446,14 @@ namespace Mingle { } // Toolbar Style - private void apply_toolbar_style () { - var style = get_toolbar_style (); - toolbar.set_top_bar_style (style); + private void apply_toolbar_view_style () { + var style = get_toolbar_view_style (); + toolbar_view.set_top_bar_style (style); + randomize_button.visible = true; + search_button.visible = true; } - private Adw.ToolbarStyle get_toolbar_style () { + private Adw.ToolbarStyle get_toolbar_view_style () { uint style = settings.get_int ("headerbar-style"); switch (style) { case 0: