diff --git a/src/packages/browse.rs b/src/packages/browse.rs index 38e1c35..5d1ca1a 100644 --- a/src/packages/browse.rs +++ b/src/packages/browse.rs @@ -1,12 +1,15 @@ use gtk::{ - prelude::{BoxExt, ButtonExt, Cast, EditableExt, ListBoxRowExt}, - Button, Window, + prelude::{BoxExt, ButtonExt, EditableExt}, + Button, PositionType, Window, }; use std::process::Command; use gtk::{Align, ListBox, ScrolledWindow, SearchBar, SearchEntry}; pub static mut PACKAGES_LIST: Option = None; +pub static mut PKG_LIST: Vec = vec![]; +pub static mut PKG_LIST_INDEX: usize = 0; +pub static mut PKG_LISTBOX: Option = None; pub fn browse() -> gtk::Box { let packages_box = gtk::Box::builder() @@ -33,6 +36,8 @@ pub fn browse() -> gtk::Box { .hexpand(true) .build(); + let skip_list = vec!["available", "installed", "last"]; + unsafe { PACKAGES_LIST = Some( ListBox::builder() @@ -54,68 +59,95 @@ pub fn browse() -> gtk::Box { ) .unwrap(); - let pkg_list = pkg_list - .lines() - .skip(1) - .map(|x| { - x.split_whitespace() - .next() - .unwrap_or("") - .split(".") - .next() - .unwrap() - }) - .filter(|x| !x.trim().is_empty()); + unsafe { + PKG_LIST = pkg_list + .lines() + .map(|x| { + let y = x.to_string(); + let b = y + .split_whitespace() + .next() + .unwrap_or("") + .split(".") + .next() + .unwrap(); + b.to_string() + }) + .filter(|x| { + !x.trim().is_empty() + && !x.contains("=") + && !skip_list.contains(&x.to_lowercase().trim()) + }) + .collect(); - for pkg in pkg_list { - let pkg_btn = Button::builder() - .label(pkg) - .css_classes(["package-name"]) - .build(); + for pkg in PKG_LIST[0..(50.min(PKG_LIST.len()))].to_vec() { + PKG_LIST_INDEX += 1; + let pkg_btn = Button::builder() + .label(pkg) + .css_classes(["package-name"]) + .build(); - pkg_btn.connect_clicked(|x| { - show_installed_package(x.label().map(|x| x.to_string()).unwrap_or("".to_owned())); - }); - unsafe { PACKAGES_LIST.as_ref().unwrap().append(&pkg_btn) }; + pkg_btn.connect_clicked(|x| { + show_installed_package(x.label().map(|x| x.to_string()).unwrap_or("".to_owned())); + }); + PACKAGES_LIST.as_ref().unwrap().append(&pkg_btn) + } } + unsafe { + PKG_LISTBOX = Some( + ScrolledWindow::builder() + .css_classes(["package-list-scrollable"]) + .valign(Align::Center) + .halign(Align::Center) + .width_request(800) + .height_request(600) + .build(), + ); + + PKG_LISTBOX + .as_ref() + .unwrap() + .connect_edge_reached(|_, edge| { + if edge == PositionType::Bottom { + for i in PKG_LIST_INDEX..((PKG_LIST_INDEX + 50).min(PKG_LIST.len())) { + let pkg_btn = Button::builder() + .label(PKG_LIST[i].as_str()) + .css_classes(["package-name"]) + .build(); + + pkg_btn.connect_clicked(|x| { + show_installed_package( + x.label().map(|x| x.to_string()).unwrap_or("".to_owned()), + ); + }); + PACKAGES_LIST.as_ref().unwrap().append(&pkg_btn); + + PKG_LIST_INDEX += 1; + } + } + }) + }; + pkgs_entry.connect_search_changed(move |x| { - let x = x.clone(); + let f = x.clone(); // TODO: Possibly refactor to use `dnf search` instead of a filter function. - unsafe { - PACKAGES_LIST.as_ref().unwrap().set_filter_func(move |y| { - y.child() - .unwrap() - .downcast::