Created search bar

This commit is contained in:
2025-09-22 13:58:59 +02:00
parent ebfd763e68
commit 9c006b0674
2 changed files with 242 additions and 155 deletions

View File

@@ -8,32 +8,72 @@ public class MainWindow
public Window Window { get; } public Window Window { get; }
private PreferencesGroup shortcutsGroup; private PreferencesGroup shortcutsGroup;
private PasswordStoreShortcutCollection shortcuts; 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() public MainWindow()
{ {
var builder = new Gtk.Builder("Keychain.UI.MainWindow.MainWindow.xml"); var builder = new Gtk.Builder("Keychain.UI.MainWindow.MainWindow.xml");
var window = builder.GetObject("main_window") as Window;
if (window == null) Window = builder.GetObject(windowId) as Window;
if (Window == null)
{ {
throw new Exception("Failed to load embedded resource MainWindow.xml"); throw new Exception("Failed to load embedded resource MainWindow.xml");
} }
Window = window;
var group = builder.GetObject("shortcuts_group") as PreferencesGroup; try
if (group == null)
{ {
throw new Exception("Failed to load UI element with ID: shortcuts_group"); shortcutsGroup = builder.GetObject(shortcutsGroupId) as PreferencesGroup;
} if (shortcutsGroup == null)
shortcutsGroup = group; throw new Exception(shortcutsGroupId);
var addButton = builder.GetObject("add_shortcut_button") as Gtk.Button; var addButton = builder.GetObject(addShortcutButtonId) as Gtk.Button;
if (addButton == null) if (addButton == null)
{ {
throw new Exception("Failed to load UI element with ID: add_shortcut_button"); throw new Exception(addShortcutButtonId);
} }
addButton.OnClicked += OnAddShortcutClicked; 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 // Initialize the observable collection with property binding
shortcuts = new PasswordStoreShortcutCollection(shortcutsGroup); shortcuts = new PasswordStoreShortcutCollection(shortcutsGroup);
@@ -46,13 +86,13 @@ public class MainWindow
dialog.Present(Window); dialog.Present(Window);
} }
public void AddShortcut(string path) private void AddShortcut(string path)
{ {
var newShortcut = new PasswordStoreShortcut(path: path); var newShortcut = new PasswordStoreShortcut(path: path);
shortcuts.Add(newShortcut); // This will automatically update the UI shortcuts.Add(newShortcut); // This will automatically update the UI
} }
public void RemoveShortcut(PasswordStoreShortcut shortcut) private void RemoveShortcut(PasswordStoreShortcut shortcut)
{ {
shortcuts.Remove(shortcut); // This will automatically update the UI shortcuts.Remove(shortcut); // This will automatically update the UI
} }
@@ -62,8 +102,21 @@ public class MainWindow
shortcuts.Add(new PasswordStoreShortcut(displayName: "Default", path: Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "/.password_store")); shortcuts.Add(new PasswordStoreShortcut(displayName: "Default", path: Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "/.password_store"));
} }
public void UpdateShortcutName(PasswordStoreShortcut shortcut, string newName) private void UpdateShortcutName(PasswordStoreShortcut shortcut, string newName)
{ {
shortcut.DisplayName = newName; // This will automatically update the UI row 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");
}
}
} }

View File

@@ -69,7 +69,6 @@
<child> <child>
<object class="GtkToggleButton" id="search_button"> <object class="GtkToggleButton" id="search_button">
<property name="icon-name">system-search-symbolic</property> <property name="icon-name">system-search-symbolic</property>
<!--<signal name="notify::active" handler="search_button_toggled_cb"/> -->
</object> </object>
</child> </child>
<child> <child>
@@ -81,6 +80,41 @@
</child> </child>
</object> </object>
</child> </child>
<property name="title-widget">
<object class="GtkStack" id="title_stack">
<property name="transition-type">slide-up-down</property>
<child>
<object class="GtkStackPage">
<property name="name">Passwords</property>
<property name="child">
<object class="AdwWindowTitle">
<property name="title">Passwords</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">Search</property>
<property name="child">
<object class="AdwClamp">
<property name="tightening-threshold">300</property>
<property name="maximum-size">400</property>
<property name="child">
<object class="GtkSearchEntry" id="search_entry">
<property name="hexpand">True</property>
<property name="placeholder-text" translatable="yes">Search passwords</property>
<!-- <signal name="search-started" handler="search_started_cb" swapped="yes"/> -->
<!-- <signal name="search-changed" handler="search_changed_cb" swapped="yes"/> -->
<!-- <signal name="stop-search" handler="stop_search_cb" swapped="yes"/> -->
</object>
</property>
</object>
</property>
</object>
</child>
</object>
</property>
</object> </object>
</child> </child>
<property name="content"> <property name="content">