aboutsummaryrefslogtreecommitdiff
path: root/src/gui/generate.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/generate.rs
parent7679fcc3a0c4fadea00a1a320938851b1518028d (diff)
add gtk3 gui
Diffstat (limited to 'src/gui/generate.rs')
-rw-r--r--src/gui/generate.rs154
1 files changed, 147 insertions, 7 deletions
diff --git a/src/gui/generate.rs b/src/gui/generate.rs
index 9fe9e3f..a7eb9e5 100644
--- a/src/gui/generate.rs
+++ b/src/gui/generate.rs
@@ -1,6 +1,13 @@
use gtk::prelude::*;
+use gtk::glib;
use super::state::{View, ViewManager};
+use std::sync::Arc;
+use std::sync::Mutex;
use std::rc::Rc;
+use std::thread;
+
+use crate::index::Index;
+use crate::index::GenState;
pub struct Generate {
vm : Rc<ViewManager>
@@ -15,16 +22,149 @@ impl View for Generate {
self.vm = vm
}
- fn make_current(&self) -> gtk::Box {
- let center = gtk::Box::new(gtk::Orientation::Vertical, 10);
- let main = gtk::Box::new(gtk::Orientation::Horizontal, 10);
- let label = gtk::Label::new(Some("Generate"));
+ fn make_current(&self) -> Option<gtk::Box> {
+ let target_dir = Arc::new(Mutex::new(String::new()));
+ let index_file = Arc::new(Mutex::new(String::new()));
+ let (index_tx, index_rx) = std::sync::mpsc::channel();
+ let load_next = Rc::new(Mutex::new(false));
+
+ let splash = gtk::Window::new(gtk::WindowType::Popup);
+ splash.set_type_hint(gtk::gdk::WindowTypeHint::Splashscreen);
+ splash.set_decorated(false);
+ splash.set_position(gtk::WindowPosition::Center);
+ splash.set_resizable(false);
+ splash.set_size_request(600, 200);
+
+ let main = gtk::Box::new(gtk::Orientation::Vertical, 10);
+ main.set_widget_name("generate");
+ let title = gtk::Label::new(Some("Generate Index"));
+ title.set_widget_name("title");
+
+ let step = gtk::Label::new(Some("Choose A Target Directory"));
+ step.set_halign(gtk::Align::Start);
+ let btn = gtk::Button::with_label("Choose");
+ btn.set_sensitive(false);
+ let header = gtk::Box::new(gtk::Orientation::Horizontal, 0);
+
+ let pick = gtk::FileChooserWidget::builder()
+ .create_folders(false)
+ .action(gtk::FileChooserAction::SelectFolder)
+ .build();
+
+ header.pack_start(&step, true, true, 10);
+ header.pack_start(&btn, false, false, 10);
+
+ main.pack_start(&title, false, false, 0);
+ main.pack_start(&header, false, false, 0);
+ main.pack_start(&pick, true, true, 0);
+
+ splash.add(&main);
+
+ pick.connect_selection_changed(glib::clone!(@weak btn => move |pick| {
+ if pick.file().is_some() || pick.current_name().is_some() {
+ btn.set_sensitive(true);
+ } else {
+ btn.set_sensitive(false);
+ }
+ }));
+
+ {
+ let target_dir = Arc::clone(&target_dir);
+ let index_file = Arc::clone(&index_file);
+ let load_next = Rc::clone(&load_next);
+ btn.connect_clicked(glib::clone!(
+ @weak splash,
+ @weak header,
+ @weak step,
+ @weak pick,
+ @weak main => move |btn| {
+ let td = { target_dir.lock().unwrap().clone() };
+
+ if td.is_empty() {
+ let uri = pick.uri().unwrap();
+ let path = uri.as_str().trim_start_matches("file://");
+ let mut target_dir = target_dir.lock().unwrap();
+ *target_dir = path.to_string();
+ step.set_text("Create A Index File");
+ btn.set_label("Create");
+ pick.set_action(gtk::FileChooserAction::Save);
+ } else {
+ let mut path = pick.current_folder().unwrap().to_str().unwrap().to_string();
+ path += "/";
+ path += pick.current_name().unwrap().to_string().as_str();
+ *index_file.lock().unwrap() = path;
+
+ main.remove(&header);
+ main.remove(&pick);
+
+ let progress = gtk::ProgressBar::builder()
+ .ellipsize(gtk::pango::EllipsizeMode::Middle)
+ .show_text(true)
+ .text("Generating")
+ .build();
+
+ progress.set_margin(20);
+ main.pack_start(&progress, true, false, 0);
+
+ let (tx, rx) = glib::MainContext::channel(glib::Priority::default());
+ {
+ let target_dir = Arc::clone(&target_dir);
+ let index_file = Arc::clone(&index_file);
+ let index_tx = index_tx.clone();
+ thread::spawn(move || {
+ let path = target_dir.lock().unwrap().to_string();
+ let idx = Index::generate(path.as_str(), |s, p| {
+ let text = match s {
+ GenState::Fetching => { "Fetching" }
+ GenState::Parsing => { "Parsing" }
+ GenState::Merging => { "Merging" }
+ };
+ tx.send(Some((text, p))).ok();
+ });
+ tx.send(Some(("Saving", 100))).ok();
+ idx.save(index_file.lock().unwrap().to_string());
+ tx.send(None).ok();
+ index_tx.send(idx)
+ });
+ }
+
+ let load_next = Rc::clone(&load_next);
+ rx.attach(None, glib::clone!(
+ @weak splash,
+ @weak progress,
+ @weak main => @default-return glib::Continue(false), move |value| match value {
+ Some((s, p)) => {
+ progress.pulse();
+ progress.set_fraction(f64::from(p) / 100.0);
+ progress.set_text(Some(s));
+ glib::Continue(true)
+ }
+ None => {
+ splash.close();
+ *load_next.lock().unwrap() = true;
+ glib::Continue(false)
+ }
+ }));
+
+ main.show_all();
+ }
+ }));
+ }
- main.pack_start(&label, false, false, 0);
+ let vm = Rc::clone(&self.vm);
+ splash.connect_hide(move |_| {
+ if *load_next.lock().unwrap() {
+ let idx = index_rx.recv().unwrap();
+ vm.set_index(idx);
+ vm.set_current_view("search");
+ } else if vm.get_current_view() == "generate" {
+ vm.set_current_view("welcome")
+ }
+ });
- center.pack_start(&main, true, false, 0);
+ splash.show_all();
- center
+ None
}
}