aboutsummaryrefslogtreecommitdiff
path: root/src/gui/search.rs
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2023-07-26 21:19:59 +0200
committerNathan Reiner <nathan@nathanreiner.xyz>2023-07-26 21:19:59 +0200
commit61ac9375b4a35878576ac2727c5210cd9fc51a92 (patch)
tree5e147ad0c60b35a83baab3f84143d3c40a09cdcd /src/gui/search.rs
parent7679fcc3a0c4fadea00a1a320938851b1518028d (diff)
add gtk3 gui
Diffstat (limited to 'src/gui/search.rs')
-rw-r--r--src/gui/search.rs133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/gui/search.rs b/src/gui/search.rs
new file mode 100644
index 0000000..a1c6ff3
--- /dev/null
+++ b/src/gui/search.rs
@@ -0,0 +1,133 @@
+use gtk::gdk::keys::constants::Return as RETURN;
+use gtk::glib;
+use gtk::prelude::*;
+use super::state::{View, ViewManager};
+use std::rc::Rc;
+use std::thread;
+
+pub struct Search {
+ vm : Rc<ViewManager>
+}
+
+impl View for Search {
+ fn name(&self) -> &str {
+ "search"
+ }
+
+ fn set_vm(&mut self, vm : Rc<ViewManager>) {
+ self.vm = vm
+ }
+
+ fn make_current(&self) -> Option<gtk::Box> {
+ let main = gtk::Box::new(gtk::Orientation::Vertical, 0);
+ let scroll = gtk::ScrolledWindow::new(gtk::Adjustment::NONE, gtk::Adjustment::NONE);
+ let search = gtk::SearchEntry::new();
+ let progress = gtk::ProgressBar::new();
+ search.set_widget_name("search_entry");
+ main.pack_start(&search, false, false, 0);
+ main.pack_start(&progress, false, false, 0);
+ let list = gtk::ListBox::new();
+ scroll.add(&list);
+
+ let empty_container = gtk::Box::new(gtk::Orientation::Vertical, 0);
+
+ let bt = include_bytes!("icon.svg");
+ let loader = gtk::gdk_pixbuf::PixbufLoader::new();
+ loader.write(bt).ok();
+ loader.set_size(200, 200);
+ loader.close().ok();
+ let pixbuf = loader.pixbuf().unwrap();
+ let image = gtk::Image::from_pixbuf(Some(&pixbuf));
+
+ empty_container.pack_start(&image, true, true, 0);
+ main.pack_start(&empty_container, true, true, 0);
+
+ let vm = Rc::clone(&self.vm);
+ search.connect_key_press_event(glib::clone!(
+ @strong scroll,
+ @strong list,
+ @weak progress,
+ @weak main,
+ @weak empty_container => @default-return gtk::Inhibit(false), move |entry, event| {
+ match event.keyval() {
+ RETURN => {
+ let query = entry.text().to_string();
+
+ if query.is_empty() {
+ main.remove(&scroll);
+ main.remove(&empty_container);
+ main.pack_start(&empty_container, true, true, 0);
+ return gtk::Inhibit(false);
+ }
+
+ let (tx, rx) = glib::MainContext::channel(glib::Priority::default());
+ let (status_tx, status_rx) = glib::MainContext::channel(glib::Priority::default());
+
+ let index = vm.get_index();
+ thread::spawn(move || {
+ let searchvec = crate::splitter::split_to_words(query);
+ let results = index.lock().unwrap().search(searchvec, |p| {
+ status_tx.send(p).ok();
+ });
+ tx.send(results).ok();
+ });
+
+ status_rx.attach(None, glib::clone!(
+ @weak progress => @default-return glib::Continue(true), move |p| {
+ progress.set_fraction(f64::from(p) / 100.0);
+
+ if p == 100 {
+ glib::Continue(false)
+ } else {
+ glib::Continue(true)
+ }
+ }));
+
+ rx.attach(None, glib::clone!(
+ @weak progress,
+ @weak list,
+ @weak scroll => @default-return glib::Continue(false), move |results| {
+ main.remove(&scroll);
+ main.remove(&empty_container);
+
+ progress.set_fraction(0.0);
+
+ if results.is_empty() {
+ main.pack_start(&empty_container, true, true, 0);
+ return glib::Continue(false);
+ } else {
+ for child in list.children() {
+ list.remove(&child);
+ }
+
+ for result in results.iter().rev().take(1000) {
+ let entry = gtk::Box::new(gtk::Orientation::Horizontal, 0);
+ entry.set_margin(10);
+ let path_label = gtk::Label::new(Some(&result.path));
+ let prio_label = gtk::Label::new(Some(&result.priority.to_string()));
+ entry.pack_start(&prio_label, false, false, 10);
+ entry.pack_start(&path_label, true, true, 10);
+ list.prepend(&entry)
+ }
+
+ main.pack_start(&scroll, true, true, 0);
+ }
+ main.show_all();
+
+ glib::Continue(false)
+ }));
+ }
+ _ => {}
+ }
+ gtk::Inhibit(false)
+ }));
+
+ Some(main)
+ }
+}
+
+impl Search {
+ pub fn new() -> Self {
+ Self { vm : Rc::new(ViewManager::empty()) }
+ }
+}