diff --git a/core/src/inner.rs b/core/src/inner.rs index a2274dfa0..ed810b06c 100644 --- a/core/src/inner.rs +++ b/core/src/inner.rs @@ -33,30 +33,18 @@ pub fn get_tabs(validate: bool) -> (TempDir, Vec) { let tabs: Vec = tabs .into_iter() - .map( - |( - TabEntry { - name, - data, - multi_selectable, - }, - directory, - )| { - let mut tree = Tree::new(Rc::new(ListNode { - name: "root".to_string(), - description: String::new(), - command: Command::None, - task_list: String::new(), - })); - let mut root = tree.root_mut(); - create_directory(data, &mut root, &directory, validate); - Tab { - name, - tree, - multi_selectable, - } - }, - ) + .map(|(TabEntry { name, data }, directory)| { + let mut tree = Tree::new(Rc::new(ListNode { + name: "root".to_string(), + description: String::new(), + command: Command::None, + task_list: String::new(), + multi_select: false, + })); + let mut root = tree.root_mut(); + create_directory(data, &mut root, &directory, validate, true); + Tab { name, tree } + }) .collect(); if tabs.is_empty() { @@ -74,12 +62,6 @@ struct TabList { struct TabEntry { name: String, data: Vec, - #[serde(default = "default_multi_selectable")] - multi_selectable: bool, -} - -fn default_multi_selectable() -> bool { - true } #[derive(Deserialize)] @@ -94,6 +76,12 @@ struct Entry { entry_type: EntryType, #[serde(default)] task_list: String, + #[serde(default = "default_true")] + multi_select: bool, +} + +fn default_true() -> bool { + true } #[derive(Deserialize)] @@ -174,8 +162,11 @@ fn create_directory( node: &mut NodeMut>, command_dir: &Path, validate: bool, + parent_multi_select: bool, ) { for entry in data { + let multi_select = parent_multi_select && entry.multi_select; + match entry.entry_type { EntryType::Entries(entries) => { let mut node = node.append(Rc::new(ListNode { @@ -183,8 +174,9 @@ fn create_directory( description: entry.description, command: Command::None, task_list: String::new(), + multi_select, })); - create_directory(entries, &mut node, command_dir, validate); + create_directory(entries, &mut node, command_dir, validate, multi_select); } EntryType::Command(command) => { node.append(Rc::new(ListNode { @@ -192,6 +184,7 @@ fn create_directory( description: entry.description, command: Command::Raw(command), task_list: String::new(), + multi_select, })); } EntryType::Script(script) => { @@ -210,6 +203,7 @@ fn create_directory( file: script, }, task_list: entry.task_list, + multi_select, })); } } diff --git a/core/src/lib.rs b/core/src/lib.rs index b7cd631e7..4e795dd34 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -23,7 +23,6 @@ pub enum Command { pub struct Tab { pub name: String, pub tree: Tree>, - pub multi_selectable: bool, } #[derive(Clone, Hash, Eq, PartialEq)] @@ -32,4 +31,5 @@ pub struct ListNode { pub description: String, pub command: Command, pub task_list: String, + pub multi_select: bool, } diff --git a/core/tabs/applications-setup/dwmtitus-setup.sh b/core/tabs/applications-setup/dwmtitus-setup.sh index 9c0f41dc4..8f68b155c 100755 --- a/core/tabs/applications-setup/dwmtitus-setup.sh +++ b/core/tabs/applications-setup/dwmtitus-setup.sh @@ -218,6 +218,9 @@ setupDisplayManager() { case "$PACKAGER" in pacman) elevated_execution "$PACKAGER" -S --needed --noconfirm "$DM" + if [ "$DM" = "lightdm" ]; then + elevated_execution "$PACKAGER" -S --needed --noconfirm lightdm-gtk-greeter + fi ;; apt-get|nala) elevated_execution "$PACKAGER" install -y "$DM" diff --git a/core/tabs/common-script.sh b/core/tabs/common-script.sh index d2444f3c7..8cbcfa6df 100644 --- a/core/tabs/common-script.sh +++ b/core/tabs/common-script.sh @@ -10,7 +10,7 @@ GREEN='\033[32m' command_exists() { for cmd in "$@"; do - export PATH=/home/jeeva/.local/share/flatpak/exports/bin:/var/lib/flatpak/exports/bin:$PATH + export PATH="$HOME/.local/share/flatpak/exports/bin:/var/lib/flatpak/exports/bin:$PATH" command -v "$cmd" >/dev/null 2>&1 || return 1 done return 0 diff --git a/core/tabs/system-setup/gaming-setup.sh b/core/tabs/system-setup/gaming-setup.sh index 2d3f2e94b..556f7791a 100755 --- a/core/tabs/system-setup/gaming-setup.sh +++ b/core/tabs/system-setup/gaming-setup.sh @@ -21,12 +21,12 @@ installDepend() { alsa-utils alsa-plugins lib32-alsa-plugins alsa-lib lib32-alsa-lib giflib lib32-giflib libpng lib32-libpng \ libldap lib32-libldap openal lib32-openal libxcomposite lib32-libxcomposite libxinerama lib32-libxinerama \ ncurses lib32-ncurses vulkan-icd-loader lib32-vulkan-icd-loader ocl-icd lib32-ocl-icd libva lib32-libva \ - gst-plugins-base-libs lib32-gst-plugins-base-libs sdl2" + gst-plugins-base-libs lib32-gst-plugins-base-libs sdl2 lib32-sdl2 v4l-utils lib32-v4l-utils sqlite lib32-sqlite" $AUR_HELPER -S --needed --noconfirm $DEPENDENCIES $DISTRO_DEPS ;; apt-get|nala) - DISTRO_DEPS="libasound2 libsdl2 wine64 wine32" + DISTRO_DEPS="libasound2-plugins:i386 libsdl2-2.0-0:i386 libdbus-1-3:i386 libsqlite3-0:i386 wine64 wine32" elevated_execution "$PACKAGER" update elevated_execution dpkg --add-architecture i386 @@ -36,7 +36,7 @@ installDepend() { elevated_execution "$PACKAGER" install -y $DEPENDENCIES $DISTRO_DEPS ;; dnf) - if [ "$(rpm -E %fedora)" -le 41 ]; then + if [ "$(rpm -E %fedora)" -le 41 ]; then elevated_execution "$PACKAGER" install ffmpeg ffmpeg-libs -y elevated_execution "$PACKAGER" install -y $DEPENDENCIES else @@ -69,7 +69,7 @@ installAdditionalDepend() { version_no_v=$(echo "$version" | tr -d v) curl -sSLo "lutris_${version_no_v}_all.deb" "https://github.com/lutris/lutris/releases/download/${version}/lutris_${version_no_v}_all.deb" - + printf "%b\n" "${YELLOW}Installing Lutris...${RC}" elevated_execution "$PACKAGER" install ./lutris_"${version_no_v}"_all.deb diff --git a/core/tabs/system-setup/tab_data.toml b/core/tabs/system-setup/tab_data.toml index 850ef38ed..b912cd6c9 100644 --- a/core/tabs/system-setup/tab_data.toml +++ b/core/tabs/system-setup/tab_data.toml @@ -1,5 +1,4 @@ name = "System Setup" -multi_selectable = false [[data]] name = "Arch Linux" @@ -14,6 +13,7 @@ name = "Arch Server Setup" description = "This command installs a minimal arch server setup under 5 minutes." script = "arch/server-setup.sh" task_list = "SI D" +multi_select = false [[data.entries]] name = "Paru AUR Helper" @@ -82,12 +82,14 @@ name = "Full System Cleanup" description = "This script is designed to remove unnecessary packages, clean old cache files, remove temporary files, and to empty the trash." script = "system-cleanup.sh" task_list = "RP PFM" +multi_select = false [[data]] name = "Full System Update" description = "This command updates your system to the latest packages available for your distro" script = "system-update.sh" task_list = "PFM" +multi_select = false [[data]] name = "Gaming Dependencies" diff --git a/core/tabs/utils/tab_data.toml b/core/tabs/utils/tab_data.toml index 00b68edf1..a0f6d50ec 100644 --- a/core/tabs/utils/tab_data.toml +++ b/core/tabs/utils/tab_data.toml @@ -1,8 +1,8 @@ name = "Utilities" -multi_selectable = false [[data]] name = "Monitor Control" +multi_select = false [[data.preconditions]] matches = true @@ -78,6 +78,7 @@ script = "monitor-control/set_resolutions.sh" [[data]] name = "User Account Manager" +multi_select = false [[data.entries]] name = "Add User" @@ -104,6 +105,7 @@ name = "Auto Mount Drive" description = "This utility is designed to help with automating the process of mounting a drive on to your system." script = "auto-mount.sh" task_list = "PFM" +multi_select = false [[data]] name = "Auto Login" @@ -120,6 +122,7 @@ name = "Bluetooth Manager" description = "This utility is designed to manage bluetooth in your system" script = "bluetooth-control.sh" task_list = "I SS" +multi_select = false [[data]] name = "Bootable USB Creator" diff --git a/tui/src/state.rs b/tui/src/state.rs index a07bf1780..3670c779d 100644 --- a/tui/src/state.rs +++ b/tui/src/state.rs @@ -153,12 +153,10 @@ impl AppState { hints.push(Shortcut::new("Select item below", ["j", "Down"])); hints.push(Shortcut::new("Next theme", ["t"])); hints.push(Shortcut::new("Previous theme", ["T"])); - - if self.is_current_tab_multi_selectable() { - hints.push(Shortcut::new("Toggle multi-selection mode", ["v"])); + hints.push(Shortcut::new("Multi-selection mode", ["v"])); + if self.multi_select { hints.push(Shortcut::new("Select multiple commands", ["Space"])); } - hints.push(Shortcut::new("Next tab", ["Tab"])); hints.push(Shortcut::new("Previous tab", ["Shift-Tab"])); hints.push(Shortcut::new("Important actions guide", ["g"])); @@ -330,7 +328,12 @@ impl AppState { let (indicator, style) = if is_selected { (self.theme.multi_select_icon(), Style::default().bold()) } else { - ("", Style::new()) + let ms_style = if self.multi_select && !node.multi_select { + Style::default().fg(self.theme.multi_select_disabled_color()) + } else { + Style::new() + }; + ("", ms_style) }; if *has_children { Line::from(format!( @@ -340,6 +343,7 @@ impl AppState { indicator )) .style(self.theme.dir_color()) + .patch_style(style) } else { Line::from(format!( "{} {} {}", @@ -357,13 +361,21 @@ impl AppState { |ListEntry { node, has_children, .. }| { + let ms_style = if self.multi_select && !node.multi_select { + Style::default().fg(self.theme.multi_select_disabled_color()) + } else { + Style::new() + }; if *has_children { - Line::from(" ").style(self.theme.dir_color()) + Line::from(" ") + .style(self.theme.dir_color()) + .patch_style(ms_style) } else { Line::from(format!("{} ", node.task_list)) .alignment(Alignment::Right) .style(self.theme.cmd_color()) .bold() + .patch_style(ms_style) } }, )); @@ -479,6 +491,13 @@ impl AppState { // enabled, need to clear it to prevent state corruption if !self.multi_select { self.selected_commands.clear() + } else { + // Prevents non multi_selectable cmd from being pushed into the selected list + if let Some(node) = self.get_selected_node() { + if !node.multi_select { + self.selected_commands.retain(|cmd| cmd.name != node.name); + } + } } } ConfirmStatus::Confirm => self.handle_confirm_command(), @@ -556,41 +575,31 @@ impl AppState { } fn toggle_multi_select(&mut self) { - if self.is_current_tab_multi_selectable() { - self.multi_select = !self.multi_select; - if !self.multi_select { - self.selected_commands.clear(); - } + self.multi_select = !self.multi_select; + if !self.multi_select { + self.selected_commands.clear(); } } fn toggle_selection(&mut self) { - if let Some(command) = self.get_selected_node() { - if self.selected_commands.contains(&command) { - self.selected_commands.retain(|c| c != &command); - } else { - self.selected_commands.push(command); + if let Some(node) = self.get_selected_node() { + if node.multi_select { + if self.selected_commands.contains(&node) { + self.selected_commands.retain(|c| c != &node); + } else { + self.selected_commands.push(node); + } } } } - pub fn is_current_tab_multi_selectable(&self) -> bool { - let index = self.current_tab.selected().unwrap_or(0); - self.tabs - .get(index) - .map_or(false, |tab| tab.multi_selectable) - } - fn update_items(&mut self) { self.filter.update_items( &self.tabs, self.current_tab.selected().unwrap(), self.visit_stack.last().unwrap().0, ); - if !self.is_current_tab_multi_selectable() { - self.multi_select = false; - self.selected_commands.clear(); - } + let len = self.filter.item_list().len(); if len > 0 { let current = self.selection.selected().unwrap_or(0); diff --git a/tui/src/theme.rs b/tui/src/theme.rs index 8337645a2..d87e87ee1 100644 --- a/tui/src/theme.rs +++ b/tui/src/theme.rs @@ -28,6 +28,13 @@ impl Theme { } } + pub fn multi_select_disabled_color(&self) -> Color { + match self { + Theme::Default => Color::DarkGray, + Theme::Compatible => Color::DarkGray, + } + } + pub fn tab_color(&self) -> Color { match self { Theme::Default => Color::Rgb(255, 255, 85),