Skip to content

Commit

Permalink
#415: Account for filtered games in status row and toggle-all buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
mtkennerly committed Dec 20, 2024
1 parent 298dc8b commit 3be4a58
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 46 deletions.
40 changes: 30 additions & 10 deletions src/gui/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2173,17 +2173,27 @@ impl App {
Message::SelectAllGames => {
match self.screen {
Screen::Backup => {
for entry in &self.backup_screen.log.entries {
self.config.enable_game_for_backup(&entry.scan_info.game_name);
for name in self.backup_screen.log.visible_games(
ScanKind::Backup,
&self.config,
&self.manifest.extended,
&self.backup_screen.duplicate_detector,
) {
self.config.enable_game_for_backup(&name);
}
}
Screen::Restore => {
for entry in &self.restore_screen.log.entries {
self.config.enable_game_for_restore(&entry.scan_info.game_name);
for name in self.restore_screen.log.visible_games(
ScanKind::Restore,
&self.config,
&self.manifest.extended,
&self.restore_screen.duplicate_detector,
) {
self.config.enable_game_for_restore(&name);
}
}
Screen::CustomGames => {
for i in 0..self.config.custom_games.len() {
for i in self.custom_games_screen.visible_games(&self.config) {
self.config.enable_custom_game(i);
}
}
Expand All @@ -2195,17 +2205,27 @@ impl App {
Message::DeselectAllGames => {
match self.screen {
Screen::Backup => {
for entry in &self.backup_screen.log.entries {
self.config.disable_game_for_backup(&entry.scan_info.game_name);
for name in self.backup_screen.log.visible_games(
ScanKind::Backup,
&self.config,
&self.manifest.extended,
&self.backup_screen.duplicate_detector,
) {
self.config.disable_game_for_backup(&name);
}
}
Screen::Restore => {
for entry in &self.restore_screen.log.entries {
self.config.disable_game_for_restore(&entry.scan_info.game_name);
for name in self.restore_screen.log.visible_games(
ScanKind::Restore,
&self.config,
&self.manifest.extended,
&self.restore_screen.duplicate_detector,
) {
self.config.disable_game_for_restore(&name);
}
}
Screen::CustomGames => {
for i in 0..self.config.custom_games.len() {
for i in self.custom_games_screen.visible_games(&self.config) {
self.config.disable_custom_game(i);
}
}
Expand Down
20 changes: 14 additions & 6 deletions src/gui/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,34 +263,42 @@ pub fn previous_page<'a>(action: impl Fn(usize) -> Message, page: usize) -> Elem
template(Icon::ArrowBack.text(), (page > 0).then(|| action(page - 1)), None)
}

pub fn toggle_all_scanned_games<'a>(all_enabled: bool) -> Element<'a> {
pub fn toggle_all_scanned_games<'a>(all_enabled: bool, filtered: bool) -> Element<'a> {
if all_enabled {
template(
template_extended(
text(TRANSLATOR.disable_all_button()).width(WIDTH),
Some(Message::DeselectAllGames),
None,
filtered.then_some(Icon::Filter),
filtered.then(|| TRANSLATOR.operation_will_only_include_listed_games()),
)
} else {
template(
template_extended(
text(TRANSLATOR.enable_all_button()).width(WIDTH),
Some(Message::SelectAllGames),
None,
filtered.then_some(Icon::Filter),
filtered.then(|| TRANSLATOR.operation_will_only_include_listed_games()),
)
}
}

pub fn toggle_all_custom_games<'a>(all_enabled: bool) -> Element<'a> {
pub fn toggle_all_custom_games<'a>(all_enabled: bool, filtered: bool) -> Element<'a> {
if all_enabled {
template(
template_extended(
text(TRANSLATOR.disable_all_button()).width(WIDTH),
Some(Message::DeselectAllGames),
None,
filtered.then_some(Icon::Filter),
filtered.then(|| TRANSLATOR.operation_will_only_include_listed_games()),
)
} else {
template(
template_extended(
text(TRANSLATOR.enable_all_button()).width(WIDTH),
Some(Message::SelectAllGames),
None,
filtered.then_some(Icon::Filter),
filtered.then(|| TRANSLATOR.operation_will_only_include_listed_games()),
)
}
}
Expand Down
57 changes: 36 additions & 21 deletions src/gui/game_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,26 +393,29 @@ pub struct GameList {
}

impl GameList {
pub fn duplicatees(&self, duplicate_detector: &DuplicateDetector) -> Option<HashSet<String>> {
self.filter_duplicates_of.as_ref().and_then(|game| {
let mut duplicatees = duplicate_detector.duplicate_games(game);
if duplicatees.is_empty() {
None
} else {
duplicatees.insert(game.clone());
Some(duplicatees)
}
})
}

pub fn view(
&self,
scan_kind: ScanKind,
config: &Config,
manifest: &Manifest,
duplicate_detector: &DuplicateDetector,
duplicatees: Option<&HashSet<String>>,
operation: &Operation,
histories: &TextHistories,
modifiers: &Modifiers,
) -> Container {
let duplicatees = self.filter_duplicates_of.as_ref().and_then(|game| {
let mut duplicatees = duplicate_detector.duplicate_games(game);
if duplicatees.is_empty() {
None
} else {
duplicatees.insert(game.clone());
Some(duplicatees)
}
});

Container::new(
Column::new()
.spacing(15)
Expand All @@ -432,14 +435,7 @@ impl GameList {
.entries
.iter()
.filter(|entry| {
self.filter_game(
entry,
scan_kind,
config,
manifest,
duplicate_detector,
duplicatees.as_ref(),
)
self.filter_game(entry, scan_kind, config, manifest, duplicate_detector, duplicatees)
})
.fold(
Column::new()
Expand All @@ -465,9 +461,17 @@ impl GameList {
)
}

pub fn all_entries_selected(&self, config: &Config, scan_kind: ScanKind) -> bool {
pub fn all_visible_entries_selected(
&self,
config: &Config,
scan_kind: ScanKind,
manifest: &Manifest,
duplicate_detector: &DuplicateDetector,
duplicatees: Option<&HashSet<String>>,
) -> bool {
self.entries
.iter()
.filter(|entry| self.filter_game(entry, scan_kind, config, manifest, duplicate_detector, duplicatees))
.all(|x| config.is_game_enabled_for_operation(&x.scan_info.game_name, scan_kind))
}

Expand All @@ -484,7 +488,7 @@ impl GameList {
&entry.scan_info.game_name,
scan_kind,
entry.scan_info.overall_change().is_changed(),
entry.scan_info.found_anything(),
entry.scanned,
);

let qualifies = self.search.qualifies(
Expand Down Expand Up @@ -541,9 +545,20 @@ impl GameList {
self.search.show || self.filter_duplicates_of.is_some()
}

pub fn compute_operation_status(&self, config: &Config, scan_kind: ScanKind) -> OperationStatus {
pub fn compute_operation_status(
&self,
config: &Config,
scan_kind: ScanKind,
manifest: &Manifest,
duplicate_detector: &DuplicateDetector,
duplicatees: Option<&HashSet<String>>,
) -> OperationStatus {
let mut status = OperationStatus::default();
for entry in self.entries.iter() {
if !self.filter_game(entry, scan_kind, config, manifest, duplicate_detector, duplicatees) {
continue;
}

status.total_games += 1;
status.total_bytes += entry.scan_info.total_possible_bytes();
if !entry.scan_info.all_ignored()
Expand Down
66 changes: 61 additions & 5 deletions src/gui/screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ impl Backup {
) -> Element {
let sort = &config.backup.sort;

let duplicatees = self.log.duplicatees(&self.duplicate_detector);

let content = Column::new()
.push(
Row::new()
Expand All @@ -94,12 +96,25 @@ impl Backup {
.push(button::backup_preview(operation, self.log.is_filtered()))
.push(button::backup(operation, self.log.is_filtered()))
.push(button::toggle_all_scanned_games(
self.log.all_entries_selected(config, Self::SCAN_KIND),
self.log.all_visible_entries_selected(
config,
Self::SCAN_KIND,
manifest,
&self.duplicate_detector,
duplicatees.as_ref(),
),
self.log.is_filtered(),
))
.push(button::filter(self.log.search.show)),
)
.push(make_status_row(
&self.log.compute_operation_status(config, Self::SCAN_KIND),
&self.log.compute_operation_status(
config,
Self::SCAN_KIND,
manifest,
&self.duplicate_detector,
duplicatees.as_ref(),
),
self.duplicate_detector.overall(),
))
.push(
Expand All @@ -123,6 +138,7 @@ impl Backup {
config,
manifest,
&self.duplicate_detector,
duplicatees.as_ref(),
operation,
histories,
modifiers,
Expand Down Expand Up @@ -158,6 +174,8 @@ impl Restore {
) -> Element {
let sort = &config.restore.sort;

let duplicatees = self.log.duplicatees(&self.duplicate_detector);

let content = Column::new()
.push(
Row::new()
Expand All @@ -167,13 +185,26 @@ impl Restore {
.push(button::restore_preview(operation, self.log.is_filtered()))
.push(button::restore(operation, self.log.is_filtered()))
.push(button::toggle_all_scanned_games(
self.log.all_entries_selected(config, Self::SCAN_KIND),
self.log.all_visible_entries_selected(
config,
Self::SCAN_KIND,
manifest,
&self.duplicate_detector,
duplicatees.as_ref(),
),
self.log.is_filtered(),
))
.push(button::validate_backups(operation))
.push(button::filter(self.log.search.show)),
)
.push(make_status_row(
&self.log.compute_operation_status(config, Self::SCAN_KIND),
&self.log.compute_operation_status(
config,
Self::SCAN_KIND,
manifest,
&self.duplicate_detector,
duplicatees.as_ref(),
),
self.duplicate_detector.overall(),
))
.push(
Expand All @@ -197,6 +228,7 @@ impl Restore {
config,
manifest,
&self.duplicate_detector,
duplicatees.as_ref(),
operation,
histories,
modifiers,
Expand Down Expand Up @@ -227,7 +259,10 @@ impl CustomGames {
.spacing(20)
.align_y(Alignment::Center)
.push(button::add_game())
.push(button::toggle_all_custom_games(config.are_all_custom_games_enabled()))
.push(button::toggle_all_custom_games(
self.all_visible_game_selected(config),
self.is_filtered(),
))
.push(button::sort(config::Event::SortCustomGames))
.push(button::filter(self.filter.enabled)),
)
Expand All @@ -243,6 +278,27 @@ impl CustomGames {

template(content)
}

fn is_filtered(&self) -> bool {
self.filter.enabled
}

pub fn visible_games(&self, config: &Config) -> Vec<usize> {
config
.custom_games
.iter()
.enumerate()
.filter_map(|(i, game)| self.filter.qualifies(game).then_some(i))
.collect()
}

fn all_visible_game_selected(&self, config: &Config) -> bool {
config
.custom_games
.iter()
.filter(|game| self.filter.qualifies(game))
.all(|x| !x.ignore)
}
}

pub fn other<'a>(
Expand Down
4 changes: 0 additions & 4 deletions src/resource/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1679,10 +1679,6 @@ impl Config {
&& !self.custom_games[index].name.trim().is_empty()
}

pub fn are_all_custom_games_enabled(&self) -> bool {
self.custom_games.iter().all(|x| !x.ignore)
}

pub fn expanded_roots(&self) -> Vec<Root> {
for root in &self.roots {
log::trace!(
Expand Down

0 comments on commit 3be4a58

Please sign in to comment.