diff --git a/data/inscriptions.gschema.xml.in b/data/inscriptions.gschema.xml.in index aeed32f..bfe98d9 100644 --- a/data/inscriptions.gschema.xml.in +++ b/data/inscriptions.gschema.xml.in @@ -69,5 +69,10 @@ Whether to highlight both source and target Highlights alternating colours on both source and target in the TextView + + ["", "", "", "", ""] + Five last selected language code + A list of recent selected language codes to make obvious in the UI + \ No newline at end of file diff --git a/data/inscriptions.metainfo.xml.in.in b/data/inscriptions.metainfo.xml.in.in index f514ff3..85d520c 100644 --- a/data/inscriptions.metainfo.xml.in.in +++ b/data/inscriptions.metainfo.xml.in.in @@ -79,13 +79,18 @@ - +

Touchups and enhancements

    -
  • Minor design changes. Lets do refined shit.
  • +
  • A cleaner, better thought out UI
  • Updated and extended screenshots
  • -
  • Some work into cleaner code
  • +
  • Show/hide highlighting moved to target pane
  • +
  • Enable/Disable auto translation moved to gear menu
  • +
  • Display in the language list the currently selected one
  • +
  • Switch source and language moved between both languages
  • +
  • Static pane sizes - makes more sense
  • +
  • Synchronized text zoom for both source and target
diff --git a/data/meson.build b/data/meson.build index 334999f..65eb1ab 100644 --- a/data/meson.build +++ b/data/meson.build @@ -73,6 +73,7 @@ if not windows_build # Inject some variables into the metainfo file before merging in the translations appstream_conf = configuration_data() appstream_conf.set('APP_ID', app_id) + appstream_conf.set('APP_NAME', app_name) appstream_conf.set('GETTEXT_PACKAGE', meson.project_name()) appstream_file_in = configure_file( input: 'inscriptions.metainfo.xml.in.in', diff --git a/po/POTFILES b/po/POTFILES index 074c079..a52a7a8 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -12,7 +12,6 @@ src/Widgets/Buttons/OrientationBox.vala src/Widgets/Buttons/ToggleHighlight.vala src/Widgets/Popovers/SettingsPopover.vala src/Widgets/Popovers/OptionsPopover.vala -src/Widgets/LanguageSelectionBox.vala src/Widgets/Panes/Pane.vala src/Widgets/Panes/SourcePane.vala src/Widgets/Panes/TargetPane.vala diff --git a/src/Constants.vala b/src/Constants.vala index 868a376..f1bb2fd 100644 --- a/src/Constants.vala +++ b/src/Constants.vala @@ -42,6 +42,7 @@ namespace Inscriptions { public const string KEY_VERTICAL_LAYOUT = "vertical-layout"; public const string KEY_AUTO_TRANSLATE = "auto-translate"; public const string KEY_HIGHLIGHT = "highlight"; + public const string KEY_HEATMAP = "language-heatmap"; // Backend public const string KEY_SOURCE_LANGUAGE = "source-language"; diff --git a/src/Objects/DDModel.vala b/src/Objects/DDModel.vala index 668c691..f8bb94c 100644 --- a/src/Objects/DDModel.vala +++ b/src/Objects/DDModel.vala @@ -10,7 +10,7 @@ */ public class Inscriptions.DDModel : Object { - static string[] heatmap {get; set;} + static string[] heatmap = Application.settings.get_strv (KEY_HEATMAP); public GLib.ListStore model {get; set;} public Gtk.SignalListItemFactory factory_header {get; set;} @@ -20,6 +20,8 @@ public class Inscriptions.DDModel : Object { public signal void selection_changed (string language_code_selected); public DDModel () { + //heatmap = Application.settings.get_strv (KEY_HEATMAP); + // The Langs will populate this thing model = new GLib.ListStore(typeof(Lang)); @@ -49,7 +51,29 @@ public class Inscriptions.DDModel : Object { var item = list_item.get_child () as Gtk.Label; item.label = item_language.name; + // We save up a heatmap. It is rebuilt from scratch to avoid redundant language codes + // We could check beforehand and gate this but it would affect lisibility + string[] temp_heatmap = {item_language.code}; + foreach (var recent_language_code in heatmap) { + if (recent_language_code != item_language.code) { + temp_heatmap += recent_language_code; + } + + if (temp_heatmap.length == 5) { + break; + } + } + heatmap = temp_heatmap; + Application.settings.set_strv (KEY_HEATMAP, heatmap); + + //Application.settings.set_strv (KEY_HEATMAP, heatmap); + print ("\n"); + foreach (var element in heatmap) { + print (element + " "); + } + // Tell everyone language changed + // Items are connected to this and get their shit together out of it selection_changed (item_language.code); //print ("switched to: %s %s\n".printf (item_language.name, item_language.code)); } diff --git a/src/Views/TranslationView.vala b/src/Views/TranslationView.vala index 5d65c0d..9e0efb5 100644 --- a/src/Views/TranslationView.vala +++ b/src/Views/TranslationView.vala @@ -11,7 +11,6 @@ public class Inscriptions.TranslationView : Gtk.Box { Gtk.CenterBox paned {get; set;} public Inscriptions.SourcePane source_pane; public Inscriptions.TargetPane target_pane; - private Inscriptions.LanguageSelectionBox language_selection; // Add a debounce so we aren't requesting the API constantly public uint debounce_timer_id = 0; @@ -65,20 +64,29 @@ public class Inscriptions.TranslationView : Gtk.Box { vexpand = true }; paned.start_widget = source_pane; - paned.center_widget = new Gtk.Separator (VERTICAL); + + //TRANSLATORS: This is for a button that switches source and target language + var switchlang_button = new Gtk.Button.from_icon_name ("media-playlist-repeat-symbolic") { + tooltip_markup = Granite.markup_accel_tooltip ({"I"}, _("Switch languages")) + }; + switchlang_button.action_name = TranslationView.ACTION_PREFIX + TranslationView.ACTION_SWITCH_LANG; + + + paned.center_widget = switchlang_button; //new Gtk.Separator (VERTICAL); paned.end_widget = target_pane; // paned.start_ (source_pane); // paned.append (source_pane); // paned.append (target_pane); - language_selection = new Inscriptions.LanguageSelectionBox (); - append (language_selection); + //language_selection = new Inscriptions.LanguageSelectionBox (); + //append (language_selection); append (paned); /* ---------------- CONNECTS AND BINDS ---------------- */ + // Logic for toggling the panes/layout on_orientation_toggled (); Application.settings.changed["vertical-layout"].connect (on_orientation_toggled); @@ -101,16 +109,16 @@ public class Inscriptions.TranslationView : Gtk.Box { if (if_connect) { // translate when text is entered or user changes any language or option source_pane.textview.buffer.changed.connect (on_text_to_translate); - language_selection.source_changed.connect (on_text_to_translate); - language_selection.target_changed.connect (on_text_to_translate); + source_pane.language_changed.connect (on_text_to_translate); + target_pane.language_changed.connect (on_text_to_translate); Application.settings.changed["context"].connect (on_text_to_translate); Application.settings.changed["formality"].connect (on_text_to_translate); } else { // no source_pane.textview.buffer.changed.disconnect (on_text_to_translate); - language_selection.source_changed.disconnect (on_text_to_translate); - language_selection.target_changed.disconnect (on_text_to_translate); + source_pane.language_changed.disconnect (on_text_to_translate); + target_pane.language_changed.disconnect (on_text_to_translate); Application.settings.changed["context"].disconnect (on_text_to_translate); Application.settings.changed["formality"].disconnect (on_text_to_translate); } @@ -125,17 +133,17 @@ public class Inscriptions.TranslationView : Gtk.Box { connect_all (false); // Temp variables - var newtarget = language_selection.selected_source; + var newtarget = source_pane.selected_language; var newtarget_text = source_pane.text; - var newsource = language_selection.selected_target; + var newsource = target_pane.selected_language; var newsource_text = target_pane.text; // Letsgo - language_selection.selected_source = newsource; + source_pane.selected_language = newsource; source_pane.text = newsource_text; - language_selection.selected_target = newtarget; + target_pane.selected_language = newtarget; target_pane.text = newtarget_text; source_pane.textview.refresh (); @@ -167,7 +175,7 @@ public class Inscriptions.TranslationView : Gtk.Box { * Filter not-requests, set or reset debounce_timer */ public void on_text_to_translate () { - if (language_selection.selected_source == language_selection.selected_target) { + if (source_pane.selected_language == target_pane.selected_language) { source_pane.message (_("Target language is the same as source")); return; } diff --git a/src/Widgets/Buttons/TranslateButton.vala b/src/Widgets/Buttons/TranslateButton.vala index 35f2dcf..bebe3c9 100644 --- a/src/Widgets/Buttons/TranslateButton.vala +++ b/src/Widgets/Buttons/TranslateButton.vala @@ -13,7 +13,7 @@ public class Inscriptions.TranslateButton : Granite.Bin { var translate_button = new Gtk.Button () { label = _("Translate"), tooltip_markup = Granite.markup_accel_tooltip ( - {"Return", "T"}, + {"Return", "T"}, _("Start translating the entered text") ) }; diff --git a/src/Widgets/HeaderBar.vala b/src/Widgets/HeaderBar.vala index 44443db..b27857c 100644 --- a/src/Widgets/HeaderBar.vala +++ b/src/Widgets/HeaderBar.vala @@ -17,7 +17,6 @@ public class Inscriptions.HeaderBar : Granite.Bin { Gtk.StackSwitcher title_switcher; Gtk.Revealer back_revealer; - Gtk.Button switchlang_button; Gtk.Revealer toolbar_revealer; Gtk.MenuButton popover_button; @@ -83,7 +82,6 @@ public class Inscriptions.HeaderBar : Granite.Bin { title_stack.add_child (title_switcher); title_stack.visible_child = title_label; - //TRANSLATORS: Do not translate the name itself. You can write it in your writing system if that is usually done for your language headerbar = new Gtk.HeaderBar () { title_widget = title_stack }; @@ -159,11 +157,11 @@ public class Inscriptions.HeaderBar : Granite.Bin { }; var toolbar_right = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 5); - //toolbar_right.append (translate_revealer); + + toolbar_right.append (new TranslateButton ()); toolbar_right.append (popover_button); headerbar.pack_end (toolbar_right); - headerbar.pack_end (new TranslateButton ()); child = headerbar; diff --git a/src/Widgets/LanguageDropDown.vala b/src/Widgets/LanguageDropDown.vala index 5206cb8..a47f0e7 100644 --- a/src/Widgets/LanguageDropDown.vala +++ b/src/Widgets/LanguageDropDown.vala @@ -12,20 +12,16 @@ public class Inscriptions.LanguageDropDown : Granite.Bin { Gtk.DropDown dropdown; public string selected { - owned get { return get_selected_language ();} - set { set_selected_language (value);} + owned get { return get_selected_language ();} + set { set_selected_language (value);} } public signal void language_changed (string code = ""); - public LanguageDropDown (Lang[] languages) { + construct { hexpand = true; model = new Inscriptions.DDModel (); - foreach (var language in languages) { - model.model_append (language); - } - var expression = new Gtk.PropertyExpression (typeof (Inscriptions.Lang), null, "both"); dropdown = new Gtk.DropDown (model.model, expression) { factory = model.factory_header, @@ -44,7 +40,7 @@ public class Inscriptions.LanguageDropDown : Granite.Bin { private void on_selected_language () { var selected_lang = dropdown.get_selected_item () as Lang; - print ("\nSELECTED %s\n".printf (selected_lang.code)); + //print ("\nSELECTED %s\n".printf (selected_lang.code)); language_changed (selected_lang.code); } @@ -58,4 +54,10 @@ public class Inscriptions.LanguageDropDown : Granite.Bin { var selected_lang = dropdown.get_selected_item () as Lang; return selected_lang.code; } + + public void add_languages (Lang[] languages) { + foreach (var language in languages) { + model.model_append (language); + } + } } diff --git a/src/Widgets/LanguageItem.vala b/src/Widgets/LanguageItem.vala index caa9cc3..2ac3c30 100644 --- a/src/Widgets/LanguageItem.vala +++ b/src/Widgets/LanguageItem.vala @@ -28,7 +28,8 @@ public class Inscriptions.LanguageItem : Gtk.Box { construct { selected_emblem = new Gtk.Image.from_icon_name ("emblem-default-symbolic") { visible = false, - halign = Gtk.Align.END + halign = Gtk.Align.END, + margin_end = 15 }; selected_emblem.add_css_class (Granite.STYLE_CLASS_FLAT); @@ -51,6 +52,7 @@ public class Inscriptions.LanguageItem : Gtk.Box { } public void on_position_changed (string language_code_selected) { + //print ("ADJUST! "); if (language_code_selected == language_code) { label_widget.add_css_class ("bold"); diff --git a/src/Widgets/LanguageSelectionBox.vala b/src/Widgets/LanguageSelectionBox.vala deleted file mode 100644 index 19069b7..0000000 --- a/src/Widgets/LanguageSelectionBox.vala +++ /dev/null @@ -1,100 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-3.0-or-later - * SPDX-FileCopyrightText: 2025 Stella & Charlie (teamcons.carrd.co) - */ - -/** - * Small horizontal box containing Source and Target dropdowns and a switch languages button - */ -public class Inscriptions.LanguageSelectionBox : Gtk.Box { - - public LanguageDropDown dropdown_source {get; set;} - public LanguageDropDown dropdown_target {get; set;} - - public string selected_source { - owned get { return get_selected_language (true);} - set { set_selected_language (value, true);} - } - - public string selected_target { - owned get { return get_selected_language (false);} - set { set_selected_language (value, false);} - } - - public signal void source_changed (string code = ""); - public signal void target_changed (string code = ""); - - construct { - orientation = Gtk.Orientation.HORIZONTAL; - spacing = 0; - hexpand = true; - - /* ---------------- SOURCE ---------------- */ - dropdown_source = new LanguageDropDown (Inscriptions.SourceLang ()) { - tooltip_text = _("Set the language to translate from") - }; - - //TRANSLATORS: This is for a button that switches source and target language - var switchlang_button = new Gtk.Button.from_icon_name ("media-playlist-repeat-symbolic") { - tooltip_markup = Granite.markup_accel_tooltip ({"I"}, _("Switch languages")) - }; - switchlang_button.action_name = TranslationView.ACTION_PREFIX + TranslationView.ACTION_SWITCH_LANG; - - dropdown_target = new LanguageDropDown (Inscriptions.SourceLang ()) { - tooltip_text = _("Set the language to translate to") - }; - - - - var cb = new Gtk.CenterBox () { - hexpand = true - }; - - cb.start_widget = dropdown_source; - cb.center_widget = switchlang_button; - cb.end_widget = dropdown_target; - - append (cb); - - /* ---------------- CONNECTS AND BINDS ---------------- */ - - selected_source = Application.settings.get_string (KEY_SOURCE_LANGUAGE); - selected_target = Application.settings.get_string (KEY_TARGET_LANGUAGE); - - dropdown_source.language_changed.connect (on_source_changed); - dropdown_target.language_changed.connect (on_target_changed); - } - - - private void set_selected_language (string code, bool is_source) { - if (is_source) { - dropdown_source.selected = code; - - } else { - dropdown_target.selected = code; - } - - print ("Set " + code + " Source?" + is_source.to_string () + "\n"); - } - - private string get_selected_language (bool is_source) { - if (is_source) { - //print ("is selected " + selected.code + selected.name + "\n"); - return dropdown_source.selected; - - } else { - //print ("is selected " + selected.code + selected.name + "\n"); - return dropdown_target.selected; - } - } - - private void on_source_changed (string language_code) { - Application.settings.set_string (KEY_SOURCE_LANGUAGE, language_code); - source_changed (language_code); - } - - private void on_target_changed (string language_code) { - Application.settings.set_string (KEY_TARGET_LANGUAGE, language_code); - target_changed (language_code); - } -} diff --git a/src/Widgets/Panes/Pane.vala b/src/Widgets/Panes/Pane.vala index 12c3f09..7505b47 100644 --- a/src/Widgets/Panes/Pane.vala +++ b/src/Widgets/Panes/Pane.vala @@ -10,6 +10,7 @@ public class Inscriptions.Pane : Gtk.Box { public Inscriptions.DDModel model {get; construct;} + public Inscriptions.LanguageDropDown dropdown {get; construct;} public Inscriptions.TextView textview; public Gtk.ScrolledWindow scrolledwindow; @@ -20,15 +21,24 @@ public class Inscriptions.Pane : Gtk.Box { private Granite.Toast toast; + public string selected_language { + owned get { return dropdown.selected;} + set { dropdown.selected = value;} + } + public string text { owned get { return textview.buffer.text;} set { textview.buffer.text = value;} } + public signal void language_changed (string code = ""); + construct { orientation = Gtk.Orientation.VERTICAL; spacing = 0; + dropdown = new LanguageDropDown (); + /* ---------------- VIEW ---------------- */ textview = new Inscriptions.TextView (); textview.set_wrap_mode (Gtk.WrapMode.WORD_CHAR); @@ -52,7 +62,8 @@ public class Inscriptions.Pane : Gtk.Box { actionbar = new Gtk.ActionBar () { hexpand = true, vexpand = false, - valign = Gtk.Align.END + valign = Gtk.Align.END, + height_request = 32 }; actionbar.add_css_class (Granite.STYLE_CLASS_FLAT); @@ -71,11 +82,15 @@ public class Inscriptions.Pane : Gtk.Box { }; stack.add_child (main_view); + append (dropdown); append (stack); + /***************** CONNECTS AND BINDS *****************/ toast.default_action.connect (() => { textview.buffer.undo (); }); + + dropdown.language_changed.connect ((code) => {language_changed (code);}); } // Respectful of Undo public void replace_text (string new_text) { diff --git a/src/Widgets/Panes/SourcePane.vala b/src/Widgets/Panes/SourcePane.vala index 7cba23f..9d6e41c 100644 --- a/src/Widgets/Panes/SourcePane.vala +++ b/src/Widgets/Panes/SourcePane.vala @@ -8,9 +8,12 @@ */ public class Inscriptions.SourcePane : Inscriptions.Pane { - construct { + construct { + stack.visible_child = main_view; - // + dropdown.tooltip_text = _("Set the language to translate from"); + dropdown.add_languages (Inscriptions.SourceLang ()); + dropdown.selected = Application.settings.get_string (KEY_SOURCE_LANGUAGE); var options_button_label = new Gtk.Label (_("Options")); var options_button_box = new Gtk.Box (HORIZONTAL, 0); @@ -43,10 +46,11 @@ public class Inscriptions.SourcePane : Inscriptions.Pane { tooltip_text = _("Paste from clipboard"), margin_start = MARGIN_MENU_HALF }; - + //actionbar.pack_end (new TranslateButton () {margin_start = MARGIN_MENU_HALF}); actionbar.pack_end (clear_button); actionbar.pack_end (paste_button); + var open_button = new Gtk.Button.from_icon_name ("document-open-symbolic") { action_name = TranslationView.ACTION_PREFIX + TranslationView.ACTION_LOAD_TEXT, tooltip_markup = Granite.markup_accel_tooltip ( @@ -57,12 +61,19 @@ public class Inscriptions.SourcePane : Inscriptions.Pane { actionbar.pack_end (open_button); /***************** CONNECTS AND BINDS *****************/ + dropdown.language_changed.connect ((code) => {Application.settings.set_string (KEY_SOURCE_LANGUAGE, code);}); + paste_button.clicked.connect (paste_from_clipboard); textview.buffer.changed.connect (() => { clear_button.sensitive = (text != ""); }); } + // private void on_source_changed (string language_code) { + // Application.settings.set_string (KEY_SOURCE_LANGUAGE, language_code); + // source_changed (language_code); + // } + private void paste_from_clipboard () { var clipboard = Gdk.Display.get_default ().get_clipboard (); diff --git a/src/Widgets/Panes/TargetPane.vala b/src/Widgets/Panes/TargetPane.vala index 142b585..7708d0e 100644 --- a/src/Widgets/Panes/TargetPane.vala +++ b/src/Widgets/Panes/TargetPane.vala @@ -11,10 +11,13 @@ public class Inscriptions.TargetPane : Inscriptions.Pane { Gtk.WindowHandle placeholder_handle; Gtk.Spinner loading; Gtk.WindowHandle spin_view; - + construct { //textview.editable = false; - + dropdown.tooltip_text = _("Set the language to translate to"); + dropdown.add_languages (Inscriptions.TargetLang ()); + dropdown.selected = Application.settings.get_string (KEY_TARGET_LANGUAGE); + /* -------- PLACEHOLDER -------- */ var placeholder_box = new Gtk.Box (VERTICAL, MARGIN_MENU_BIG) { hexpand = vexpand = true, @@ -24,7 +27,7 @@ public class Inscriptions.TargetPane : Inscriptions.Pane { margin_end = MARGIN_MENU_HALF }; - var placeholder = new Gtk.Label (_("Ready!")) { + var placeholder = new Gtk.Label (_("Ready to translate")) { wrap = true }; placeholder.add_css_class (Granite.STYLE_CLASS_H2_LABEL); @@ -84,6 +87,7 @@ public class Inscriptions.TargetPane : Inscriptions.Pane { actionbar.pack_end (save_as_button); /***************** CONNECTS AND BINDS *****************/ + dropdown.language_changed.connect ((code) => {Application.settings.set_string (KEY_TARGET_LANGUAGE, code);}); Application.settings.bind ("auto-translate", auto_switcher, "active", @@ -109,6 +113,10 @@ public class Inscriptions.TargetPane : Inscriptions.Pane { } } + // private void on_target_changed (string language_code) { + // Application.settings.set_string (KEY_TARGET_LANGUAGE, language_code); + // target_changed (language_code); + // } private void copy_to_clipboard () { var clipboard = Gdk.Display.get_default ().get_clipboard (); clipboard.set_text (textview.buffer.text); diff --git a/src/meson.build b/src/meson.build index ebb64f5..18fb54a 100644 --- a/src/meson.build +++ b/src/meson.build @@ -24,7 +24,6 @@ sources = files ( 'Widgets' / 'ErrorBonusBox.vala', 'Widgets' / 'TextView.vala', 'Widgets' / 'HeaderBar.vala', - 'Widgets' / 'LanguageSelectionBox.vala', 'Widgets' / 'LanguageDropDown.vala', 'Widgets' / 'Buttons' / 'OrientationBox.vala',