using Adw; using Keychain.ViewModels; namespace Keychain.UI; public class MainWindow { public Window Window { get; } private PreferencesGroup shortcutsGroup; private PasswordStoreShortcutCollection shortcuts; private Gtk.ToggleButton searchToggleButton; private Gtk.Stack titleStack; private Gtk.SearchEntry searchEntry; private readonly string windowId = "main_window"; private readonly string shortcutsGroupId = "shortcuts_group"; private readonly string addShortcutButtonId = "add_shortcut_button"; private readonly string searchToggleButtonId = "search_button"; private readonly string titleStackId = "title_stack"; private readonly string searchEntryId = "search_entry"; public MainWindow() { var builder = new Gtk.Builder("Keychain.UI.MainWindow.MainWindow.xml"); Window = builder.GetObject(windowId) as Window; if (Window == null) { throw new Exception("Failed to load embedded resource MainWindow.xml"); } try { shortcutsGroup = builder.GetObject(shortcutsGroupId) as PreferencesGroup; if (shortcutsGroup == null) throw new Exception(shortcutsGroupId); var addButton = builder.GetObject(addShortcutButtonId) as Gtk.Button; if (addButton == null) { throw new Exception(addShortcutButtonId); } addButton.OnClicked += OnAddShortcutClicked; searchToggleButton = builder.GetObject(searchToggleButtonId) as Gtk.ToggleButton; if (searchToggleButton == null) { throw new Exception(searchToggleButtonId); } searchToggleButton.OnToggled += SetSearchBarVisible; titleStack = builder.GetObject(titleStackId) as Gtk.Stack; if (titleStack == null) { throw new Exception(titleStackId); } searchEntry = builder.GetObject(searchEntryId) as Gtk.SearchEntry; if (searchEntry == null) { throw new Exception(searchEntryId); } var focusController = new Gtk.EventControllerFocus(); focusController.OnLeave += (s, e) => { searchToggleButton.Active = false; }; searchEntry.AddController(focusController); } catch (Exception e) { throw new Exception("Failed to load UI element with ID: " + e.Message); } // Initialize the observable collection with property binding shortcuts = new PasswordStoreShortcutCollection(shortcutsGroup); LoadDefaultShortcuts(); } private void OnAddShortcutClicked(object sender, EventArgs e) { var dialog = new AddShortcutWindow().Dialog; dialog.Present(Window); } private void AddShortcut(string path) { var newShortcut = new PasswordStoreShortcut(path: path); shortcuts.Add(newShortcut); // This will automatically update the UI } private void RemoveShortcut(PasswordStoreShortcut shortcut) { shortcuts.Remove(shortcut); // This will automatically update the UI } private void LoadDefaultShortcuts() { shortcuts.Add(new PasswordStoreShortcut(displayName: "Default", path: Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "/.password_store")); } private void UpdateShortcutName(PasswordStoreShortcut shortcut, string newName) { shortcut.DisplayName = newName; // This will automatically update the UI row } private void SetSearchBarVisible(object sender, EventArgs e) { if (searchToggleButton.Active) { titleStack.SetVisibleChildName("Search"); searchEntry.GrabFocus(); } else { titleStack.SetVisibleChildName("Passwords"); } } }