ludusavi icon indicating copy to clipboard operation
ludusavi copied to clipboard

UI element to indicate that a game has been customized

Open redactedscribe opened this issue 2 years ago • 8 comments

What's your idea?

Games can be customised via the three dots menu which leads to the Custom Games tab. After a game has been customised, it's not clear via the Backup Mode tab that this is the case. Maybe this should be indicated?

What I've been doing so far is prepending an ASCII character to the start of custom game names which groups them together at the top (when ascending sort). Maybe custom game names would display with an asterisk appended to them, potentially in a colour different to the game name next? The only way to tell that a game is customised is by the Custom Games tab, or the lack of Customize in the three dot menu on the Backup Mode tab.

Questions:

  • Both user-added custom games via the Custom Games tab's Add game button is possible, and so is customising a game that was detected due to the manifest (via the three dots). Are these any different from one another?
  • For example, if we want to receive any updates to a game (thanks to new edits on PCGamingWiki), would a game detected via the manifest which has been customised receive these updates?
  • If not, maybe the updates could be offered to be merged with the user's custom paths for the custom game? Or would it be better to not allow manifest-detected games to be customised directly and for duplicates to be made of them and those customised by the user (automatically disabling the originals)?
  • Should custom games be filterable? I'm not sure how beneficial it'd be when we already have the Custom Games tab, especially if we could jump from there to the game in the Backup Mode list.

Thanks.

redactedscribe avatar Jun 26 '23 13:06 redactedscribe

Maybe this should be indicated?

That sounds like a good idea :+1: I can add a badge like this: image

Both user-added custom games via the Custom Games tab's Add game button is possible, and so is customising a game that was detected due to the manifest (via the three dots). Are these any different from one another?

Both ways achieve the same result. It's only the name field that determines whether it overrides a standard entry. The "customize" option is just a shortcut to add an entry and pre-fill the info instead of doing the same thing manually.

For example, if we want to receive any updates to a game (thanks to new edits on PCGamingWiki), would a game detected via the manifest which has been customised receive these updates?

No, the custom game fully overrides the standard one. (This is unlike secondary manifests, which are merged with the info from the primary manifest.)

If not, maybe the updates could be offered to be merged with the user's custom paths for the custom game?

Hmm, I think that might be a bit complex. Can you tell me a little bit more about your use case? My assumption has been that, if a user is making a custom entry to override a standard entry instead of editing PCGW, then they probably won't care about changes on PCGW, since they're likely doing something specific to their setup and/or they already have it "just right".

When you override a standard entry, are you generally adding new save locations or fixing/removing existing locations? Would you like to be able to have the custom entry just add on top of the standard one, instead of overriding it completely?

Or would it be better to not allow manifest-detected games to be customised directly and for duplicates to be made of them and those customised by the user (automatically disabling the originals)?

That's how it works right now. If a standard and custom entry have the same name, then the custom entry fully overrides the standard one. You can then remove save locations from the custom entry, and it will be as though the standard one doesn't have them either. If you delete the custom game, then the standard entry takes effect again.

Should custom games be filterable?

I don't mind adding a filter if there's interest, but maybe it's enough to make the "custom" badge clickable and take you to the associated entry.

mtkennerly avatar Jun 26 '23 17:06 mtkennerly

That sounds like a good idea 👍 I can add a badge like this: image

The problem I see with a badge is that we've already got (DUPLICATES) and (X of Y) badges and so in extreme cases we'd have all three eating up a lot of space. Granted, this would be rare and only really an issue when not maximised (which is how I typically view Ludusavi). Other than that, I agree, a badge is a good option.

It's only the name field that determines whether it overrides a standard entry.

That's good to know. Then I could just customise a game and append something like "(custom)" to be able to keep tabs on if the original (which I'd keep disabled) gets new paths added via an update. This is still a manual process however, but better than nothing. This would be a solution a user like me has to discover and utilise rather than something intentionally supported by the program.

Can you tell me a little bit more about your use case? My assumption has been that, if a user is making a custom entry to override a standard entry instead of editing PCGW, then they probably won't care about changes on PCGW, since they're likely doing something specific to their setup and/or they already have it "just right".

I think my argument here is that if you make a custom entry, you're right that you probably should know what you're doing and what files need backing up, but if you happen to miss a file, or more easily some reg path, then being aware that a new path has been added on PCGW that isn't a path in your custom entry could be useful. Paths can be missed and without being aware of them because the data just wasn't present on PCGW at the time of your custom entry's creation. It'd be somewhat simple for new paths, but what about changed paths on PCGW? Hmm.

Maybe the solution to this problem(?) is some UI to compare your custom entry to the overridden default entry and be able to check-mark (add) paths on the default entry side to bring over to your custom entry whilst also being able to strike out (remove) paths that would no longer be needed in your custom entry. This would be able to handle new paths and changed paths on PCGW. The issue remains that the user still has to manually decide and know to check if their custom entry is outdated so-to-speak. If Ludusavi could indicate that an entry is custom and that what it overrides has had an update, then we could go ahead and attend to the given game's paths. If the overridden game hasn't been updated but the paths simply differ to the custom entry, which is obviously expected, then don't indicate that the custom entry could be outdated.

Would you like to be able to have the custom entry just add on top of the standard one, instead of overriding it completely?

In short, yes, this is probably what I want. But what downside would this have over the complete override method that is being used currently? I'm not sure if having two types of custom entry (complete override and an additive override) would be elegant unless we could easily switch between them. Perhaps all functionality under a single unified custom entry system would be hard to implement.

It's been a bit of a mess trying to understand what I want and how Ludusavi works, but hopefully I make sense.

redactedscribe avatar Jun 26 '23 20:06 redactedscribe

in extreme cases we'd have all three eating up a lot of space. Granted, this would be rare and only really an issue when not maximised (which is how I typically view Ludusavi)

Yeah, it could end up being an issue, but I'm fine with waiting to see if anyone actually complains 😄 We may end up wanting a compact mode or some way to collapse badges together.

But what downside would this have over the complete override method that is being used currently?

The main downside is that there wouldn't be a good way to enable both behaviors at the same time for different paths, like if there's one standard path you want to keep and one you want to remove. Your diffing idea would be better for that purpose and probably easier to understand.

An alert when the standard entry changes would be harder to implement, since Ludusavi doesn't currently track how the manifest changes, but I'll see what I can do.

It's been a bit of a mess trying to understand what I want and how Ludusavi works, but hopefully I make sense.

No worries! I appreciate your feedback :D

mtkennerly avatar Jun 27 '23 07:06 mtkennerly

Just added the badge, but I think I'll have to wait for Iced 0.10.0 in order to make clicking it correctly take you to the custom game.

mtkennerly avatar Jun 28 '23 01:06 mtkennerly

Just added the badge, but I think I'll have to wait for Iced 0.10.0 in order to make clicking it correctly take you to the custom game.

Can you ping me as well when you've upgraded to clickable badges working correctly? I want to make these badges clickable as well, so that they apply the filter to show those games when clicked: image

If I try that right now, the hover makes it go wrong somehow. Like it's trying to draw text instead of the badge.

kekonn avatar Jul 04 '23 08:07 kekonn

The issue I ran into is just with the programmatic scrolling, but clickable badges do work (e.g., the game-level duplicates badge). Could you share a branch so I can take a look at the issue?

mtkennerly avatar Jul 04 '23 14:07 mtkennerly

I commited it to this branch. Only for the new badge after running preview in the backup screen. It happens on mouse over

kekonn avatar Jul 04 '23 18:07 kekonn

Ah, I see. That's related to Tooltip::snap_within_viewport. This will fix it:

diff --git a/src/gui/badge.rs b/src/gui/badge.rs
index f066e25..079c29e 100644
--- a/src/gui/badge.rs
+++ b/src/gui/badge.rs
@@ -21,6 +21,7 @@ pub struct Badge {
     on_press: Option<Message>,
     faded: bool,
     width: Option<Length>,
+    snap_tooltip: bool,
 }
 
 impl Badge {
@@ -33,6 +34,7 @@ impl Badge {
             on_press: None,
             faded: false,
             width: None,
+            snap_tooltip: true,
         }
     }
 
@@ -48,6 +50,7 @@ impl Badge {
                 ScanChange::Unknown => None,
             },
             width: Some(Length::Fixed(CHANGE_BADGE_WIDTH)),
+            snap_tooltip: true,
             ..Default::default()
         }
     }
@@ -61,6 +64,7 @@ impl Badge {
             text: format!("{}{}", crate::lang::ADD_SYMBOL, count),
             change: Some(ScanChange::New),
             tooltip: Some(TRANSLATOR.new_tooltip()),
+            snap_tooltip: true,
             ..Default::default()
         }
     }
@@ -78,6 +82,7 @@ impl Badge {
             text: format!("{}{}", crate::lang::CHANGE_SYMBOL, count),
             change: Some(ScanChange::Different),
             tooltip: Some(TRANSLATOR.updated_tooltip()),
+            snap_tooltip: true,
             ..Default::default()
         }
     }
@@ -92,6 +97,11 @@ impl Badge {
         self
     }
 
+    pub fn snap_tooltip(mut self, snap: bool) -> Self {
+        self.snap_tooltip = snap;
+        self
+    }
+
     pub fn view(self) -> Container<'static> {
         Container::new({
             let content = Container::new(
@@ -116,6 +126,7 @@ impl Badge {
                     Tooltip::new(content, tooltip, tooltip::Position::Top)
                         .size(16)
                         .gap(5)
+                        .snap_within_viewport(self.snap_tooltip)
                         .style(style::Container::Tooltip),
                 ),
             };
diff --git a/src/gui/screen.rs b/src/gui/screen.rs
index 4217745..db1c368 100644
--- a/src/gui/screen.rs
+++ b/src/gui/screen.rs
@@ -47,6 +47,7 @@ fn make_status_row<'a>(status: &OperationStatus, duplication: Duplication) -> Ro
             || {
                 Badge::new_entry_with_count(status.changed_games.new)
                     .on_press(Message::EditedSearchFilterChange(crate::scan::game_filter::Change::New))
+                    .snap_tooltip(false)
                     .view()
             },
         )

mtkennerly avatar Jul 04 '23 19:07 mtkennerly

In short, yes, this is probably what I want. But what downside would this have over the complete override method that is being used currently? I'm not sure if having two types of custom entry (complete override and an additive override) would be elegant unless we could easily switch between them. Perhaps all functionality under a single unified custom entry system would be hard to implement.

Long time coming, but I ended up implementing this for #402. Check out the demo video in that ticket and let me know what you think :)

mtkennerly avatar Oct 16 '24 19:10 mtkennerly