diff options
| author | Nathan Reiner <nathan@nathanreiner.xyz> | 2023-07-26 09:42:17 +0200 |
|---|---|---|
| committer | Nathan Reiner <nathan@nathanreiner.xyz> | 2023-07-26 09:42:17 +0200 |
| commit | 7679fcc3a0c4fadea00a1a320938851b1518028d (patch) | |
| tree | ede3c597dbef79f282e7465aeb8652f20bc0515a /src/gui/mod.rs | |
| parent | e1cb45be6575c805e3b0ab1e2d03d4047acf88d1 (diff) | |
add viewmanager
Diffstat (limited to 'src/gui/mod.rs')
| -rw-r--r-- | src/gui/mod.rs | 313 |
1 files changed, 29 insertions, 284 deletions
diff --git a/src/gui/mod.rs b/src/gui/mod.rs index 593eb65..68f8ab3 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -1,295 +1,40 @@ -use std::fs::File; -use std::io::Write; -use std::thread; -use std::time::Duration; -use iced::theme::Theme; -use iced::widget::{text, row, scrollable, container, column, button, text_input, progress_bar}; -use iced::{window, Length}; -use iced::{Application, Element}; -use iced::{Command, Settings}; -use once_cell::sync::Lazy; use std::sync::Mutex; +use std::rc::Rc; -use crate::index::Index; -use crate::searchresult::SearchResult; -use crate::splitter; -use crate::index::GenState; +use gtk::prelude::*; +use gtk::Application; -mod easing; -mod circular; +use self::state::View; -static SEARCH_ID: Lazy<text_input::Id> = Lazy::new(text_input::Id::unique); -static GENERATE_PROGRESS : Lazy<Mutex<u8>> = Lazy::new(|| { Mutex::new(0) }); -static GENERATE_STATUS : Lazy<Mutex<GenState>> = Lazy::new(|| { Mutex::new(GenState::Fetching) }); +mod state; +mod welcome; +mod generate; -pub fn run() -> iced::Result { - App::run(Settings { - window: window::Settings { - size: (1000, 800), - ..window::Settings::default() - }, - ..Settings::default() - }) -} - -#[derive(Debug)] -enum App { - StartMenu, - Generating(GenProgress), - Loading, - Search(State), -} - -#[derive(Debug, Default)] -struct State { - input_value: String, - index : Index, - results : Vec<SearchResult> -} - -struct SearchState { - search : String, - index : Index, -} - -#[derive(Debug, Clone, Default)] -struct GenProgress { - state: GenState, - progress: u8 -} - -impl SearchState { - pub async fn search(self) -> Vec<SearchResult> { - let search_args = splitter::split_to_words(self.search); - self.index.search(search_args) - } -} - -#[derive(Clone, Debug)] -enum Message { - Load, - Generate, - Loaded(Index), - GeneratingUpdate(GenProgress), - InputChanged(String), - SearchSubmit, - SearchFinished(Vec<SearchResult>), - ExportResults -} +pub fn run() { + let app = Application::builder() + .application_id("org.n8.indexsearch") + .build(); -async fn load_file() -> Index { - let file = rfd::FileDialog::new().add_filter("index", &["idxs"]) - .set_directory(".") - .set_title("Choose Index File") - .pick_file(); - let file = file.unwrap(); - let file = file.to_str(); - let file = file.unwrap(); - Index::from_file(&file.to_string()) -} + app.connect_activate(|app| { + let window = gtk::ApplicationWindow::builder() + .application(app) + .default_width(800) + .default_height(600) + .title("Index Search") + .build(); -async fn generate() -> Index { - let file = rfd::FileDialog::new().add_filter("index", &["idxs"]) - .set_directory(".") - .set_title("Choose Index File") - .save_file(); - let file = file.unwrap(); - let file = file.to_str(); - let file = file.unwrap(); + let mut vm = state::ViewManager::new(window); + let welcome = Rc::new(Mutex::new(welcome::Welcome::new())); + vm.add_view(welcome.clone()); + let generate = Rc::new(Mutex::new(generate::Generate::new())); + vm.add_view(generate.clone()); - let input = rfd::FileDialog::new() - .set_directory(".") - .set_title("Choose Directory to Index") - .pick_folder(); - let input = input.unwrap(); - let input = input.to_str(); - let input = input.unwrap(); - let index = Index::generate(input, |t, p| { - *GENERATE_PROGRESS.lock().unwrap() = p; - *GENERATE_STATUS.lock().unwrap() = t; + let vm = Rc::new(vm); + welcome.lock().unwrap().set_vm(Rc::clone(&vm)); + generate.lock().unwrap().set_vm(Rc::clone(&vm)); + vm.set_current_view("welcome"); + vm.get_window().show_all(); }); - index.save(file.to_string()); - index -} - -async fn generate_update_timer() -> GenProgress { - thread::sleep(Duration::from_millis(100)); - let p; - let s; - { - p = *GENERATE_PROGRESS.lock().unwrap(); - s = *GENERATE_STATUS.lock().unwrap(); - } - GenProgress { state : s, progress: p } -} - -impl Application for App { - type Message = Message; - type Theme = Theme; - type Executor = iced::executor::Default; - type Flags = (); - fn new(_flags: ()) -> (App, Command<Message>) { - ( - App::StartMenu, - Command::none() - ) - } - - fn title(&self) -> String { - "Index Search".to_string() - } - - fn update(&mut self, message: Message) -> Command<Message> { - match self { - App::StartMenu => { - match message { - Message::Load => { - *self = App::Loading; - Command::batch(vec![ - Command::perform(load_file(), Message::Loaded) - ]) - } - Message::Generate => { - *self = App::Generating(Default::default()); - Command::batch(vec![ - Command::perform(generate(), Message::Loaded), - Command::perform(generate_update_timer(), Message::GeneratingUpdate) - ]) - } - _ => { - Command::none() - } - } - } - App::Loading => { - match message { - Message::Loaded(index) => { - *self = App::Search(State { index, ..Default::default() }); - Command::none() - } - _ => { - Command::none() - } - } - } - App::Generating(state) => { - match message { - Message::Loaded(index) => { - *self = App::Search(State { index, ..Default::default() }); - Command::none() - } - Message::GeneratingUpdate(s) => { - state.progress = s.progress; - state.state = s.state; - Command::perform(generate_update_timer(), Message::GeneratingUpdate) - } - _ => { - Command::none() - } - } - } - App::Search(state) => { - match message { - Message::InputChanged(value) => { - state.input_value = value; - Command::none() - } - Message::SearchSubmit => { - Command::perform( - SearchState { - search: state.input_value.clone(), - index : state.index.clone() - }.search(), - Message::SearchFinished - ) - } - Message::SearchFinished(results) => { - state.results = results; - Command::none() - } - Message::ExportResults => { - let file = rfd::FileDialog::new().set_title("Export to File").add_filter("Raw Text", &["txt"]).save_file(); - if let Some(file) = file { - let mut file = File::create(file).unwrap(); - for result in state.results.iter() { - writeln!(file, "{}", result.path).ok(); - } - } - Command::none() - } - _ => { - Command::none() - } - } - } - } - } - - fn view(&self) -> Element<Message> { - let container = container(match self { - App::StartMenu => { - column![ - button("Open").on_press(Message::Load), - button("Generate").on_press(Message::Generate), - ].spacing(10).align_items(iced::Alignment::Center) - } - App::Loading => { - column![ - text("Loading"), - circular::Circular::new() - ].spacing(10).align_items(iced::Alignment::Center) - } - App::Generating(state) => { - let t = match state.state { - GenState::Fetching => { text("Fetching") } - GenState::Parsing => { text("Parsing") } - GenState::Merging => { text("Merging") } - }; - column![ - t, - progress_bar(0.0..=100.0, state.progress as f32) - ].spacing(10).align_items(iced::Alignment::Center) - } - App::Search(State { input_value, index, results, ..}) => { - let res : Element<Message> = if results.is_empty() { - column![text("There are no results")].spacing(10).into() - } else { - let lines : Vec<Element<_>> = results.iter() - .map(|r| row![text(r.priority).width(Length::Fixed(50.0)), text(r.path.clone())].into()) - .collect(); - column(lines).spacing(10).into() - }; - - column![ - row![ - text_input("Search", input_value) - .id(SEARCH_ID.clone()) - .on_submit(Message::SearchSubmit) - .on_input(Message::InputChanged) - .padding(10), - text(format!("{} files", index.num_files())) - ].align_items(iced::Alignment::Center).spacing(10), - scrollable(res).width(Length::Fill).height(Length::Fill), - row![ - text(format!("{} results", results.len())).width(Length::Fill), - button("export results").on_press(Message::ExportResults) - ].align_items(iced::Alignment::End).spacing(10) - ].spacing(10) - } - }).center_x() - .padding(10) - .width(Length::Fill) - .height(Length::Fill); - - match self { - App::Search(_) => { - container.into() - } - _ => { - container.center_y().into() - } - } - } + app.run(); } - |