Merge branch 'master' into master
This commit is contained in:
commit
45af4d2517
@ -1524,6 +1524,156 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "GameListHeaderDeveloper",
|
"ID": "GameListHeaderDeveloper",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Developed by {0}",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "GameListHeaderVersion",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "Έκδοση: {0}",
|
||||||
|
"en_US": "Version: {0}",
|
||||||
|
"es_ES": "Versión: {0}",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "Versione: {0}",
|
||||||
|
"ja_JP": "バージョン: {0}",
|
||||||
|
"ko_KR": "버전: {0}",
|
||||||
|
"no_NO": "Versjon: {0}",
|
||||||
|
"pl_PL": "Wersja: {0}",
|
||||||
|
"pt_BR": "Versão: {0}",
|
||||||
|
"ru_RU": "Версия: {0}",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "เวอร์ชั่น: {0}",
|
||||||
|
"tr_TR": "Sürüm: {0}",
|
||||||
|
"uk_UA": "Версія: {0}",
|
||||||
|
"zh_CN": "版本: {0}",
|
||||||
|
"zh_TW": "版本: {0}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "GameListHeaderTimePlayed",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "Spielzeit: {0}",
|
||||||
|
"el_GR": "Χρόνος: {0}",
|
||||||
|
"en_US": "Play Time: {0}",
|
||||||
|
"es_ES": "Tiempo jugado: {0}",
|
||||||
|
"fr_FR": "Temps de jeu: {0}",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "Tempo di gioco: {0}",
|
||||||
|
"ja_JP": "プレイ時間: {0}",
|
||||||
|
"ko_KR": "플레이 타임: {0}",
|
||||||
|
"no_NO": "Spilletid: {0}",
|
||||||
|
"pl_PL": "Czas w grze: {0}",
|
||||||
|
"pt_BR": "Tempo de jogo: {0}",
|
||||||
|
"ru_RU": "Время в игре: {0}",
|
||||||
|
"sv_SE": "Speltid: {0}",
|
||||||
|
"th_TH": "เล่นไปแล้ว: {0}",
|
||||||
|
"tr_TR": "Oynama Süresi: {0}",
|
||||||
|
"uk_UA": "Зіграно часу: {0}",
|
||||||
|
"zh_CN": "游玩时长: {0}",
|
||||||
|
"zh_TW": "遊玩時數: {0}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "GameListHeaderLastPlayed",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "Zuletzt gespielt: {0}",
|
||||||
|
"el_GR": "Παίχτηκε: {0}",
|
||||||
|
"en_US": "Last Played: {0}",
|
||||||
|
"es_ES": "Jugado por última vez: {0}",
|
||||||
|
"fr_FR": "Dernière partie jouée: {0}",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "Ultima partita: {0}",
|
||||||
|
"ja_JP": "最終プレイ日時: {0}",
|
||||||
|
"ko_KR": "마지막 플레이: {0}",
|
||||||
|
"no_NO": "Sist Spilt: {0}",
|
||||||
|
"pl_PL": "Ostatnio grane: {0}",
|
||||||
|
"pt_BR": "Último jogo: {0}",
|
||||||
|
"ru_RU": "Последний запуск: {0}",
|
||||||
|
"sv_SE": "Senast spelad: {0}",
|
||||||
|
"th_TH": "เล่นล่าสุด: {0}",
|
||||||
|
"tr_TR": "Son Oynama Tarihi: {0}",
|
||||||
|
"uk_UA": "Востаннє зіграно: {0}",
|
||||||
|
"zh_CN": "最近游玩: {0}",
|
||||||
|
"zh_TW": "最近遊玩: {0}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "GameListHeaderFileExtension",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "Dateiformat: {0}",
|
||||||
|
"el_GR": "Κατάληξη: {0}",
|
||||||
|
"en_US": "Extension: {0}",
|
||||||
|
"es_ES": "Extensión: {0}",
|
||||||
|
"fr_FR": "Extension du Fichier: {0}",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "Estensione: {0}",
|
||||||
|
"ja_JP": "ファイル拡張子: {0}",
|
||||||
|
"ko_KR": "파일 확장자: {0}",
|
||||||
|
"no_NO": "Fil Eks.: {0}",
|
||||||
|
"pl_PL": "Rozszerzenie pliku: {0}",
|
||||||
|
"pt_BR": "Extensão: {0}",
|
||||||
|
"ru_RU": "Расширение файла: {0}",
|
||||||
|
"sv_SE": "Filänd: {0}",
|
||||||
|
"th_TH": "นามสกุลไฟล์: {0}",
|
||||||
|
"tr_TR": "Dosya Uzantısı: {0}",
|
||||||
|
"uk_UA": "Розширення файлу: {0}",
|
||||||
|
"zh_CN": "扩展名: {0}",
|
||||||
|
"zh_TW": "副檔名: {0}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "GameListHeaderFileSize",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "Dateigröße: {0}",
|
||||||
|
"el_GR": "Μέγεθος Αρχείου: {0}",
|
||||||
|
"en_US": "File Size: {0}",
|
||||||
|
"es_ES": "Tamaño del archivo: {0}",
|
||||||
|
"fr_FR": "Taille du Fichier: {0}",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "Dimensione file: {0}",
|
||||||
|
"ja_JP": "ファイルサイズ: {0}",
|
||||||
|
"ko_KR": "파일 크기: {0}",
|
||||||
|
"no_NO": "Fil Størrelse: {0}",
|
||||||
|
"pl_PL": "Rozmiar pliku: {0}",
|
||||||
|
"pt_BR": "Tamanho: {0}",
|
||||||
|
"ru_RU": "Размер файла: {0}",
|
||||||
|
"sv_SE": "Filstorlek: {0}",
|
||||||
|
"th_TH": "ขนาดไฟล์: {0}",
|
||||||
|
"tr_TR": "Dosya Boyutu: {0}",
|
||||||
|
"uk_UA": "Розмір файлу: {0}",
|
||||||
|
"zh_CN": "大小: {0}",
|
||||||
|
"zh_TW": "檔案大小: {0}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "GameListSortDeveloper",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "المطور",
|
"ar_SA": "المطور",
|
||||||
"de_DE": "Entwickler",
|
"de_DE": "Entwickler",
|
||||||
@ -1548,32 +1698,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "GameListHeaderVersion",
|
"ID": "GameListSortTimePlayed",
|
||||||
"Translations": {
|
|
||||||
"ar_SA": "الإصدار",
|
|
||||||
"de_DE": "",
|
|
||||||
"el_GR": "Έκδοση",
|
|
||||||
"en_US": "Version",
|
|
||||||
"es_ES": "Versión",
|
|
||||||
"fr_FR": "",
|
|
||||||
"he_IL": "גרסה",
|
|
||||||
"it_IT": "Versione",
|
|
||||||
"ja_JP": "バージョン",
|
|
||||||
"ko_KR": "버전",
|
|
||||||
"no_NO": "Versjon",
|
|
||||||
"pl_PL": "Wersja",
|
|
||||||
"pt_BR": "Versão",
|
|
||||||
"ru_RU": "Версия",
|
|
||||||
"sv_SE": "",
|
|
||||||
"th_TH": "เวอร์ชั่น",
|
|
||||||
"tr_TR": "Sürüm",
|
|
||||||
"uk_UA": "Версія",
|
|
||||||
"zh_CN": "版本",
|
|
||||||
"zh_TW": "版本"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ID": "GameListHeaderTimePlayed",
|
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "وقت اللعب",
|
"ar_SA": "وقت اللعب",
|
||||||
"de_DE": "Spielzeit",
|
"de_DE": "Spielzeit",
|
||||||
@ -1598,7 +1723,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "GameListHeaderLastPlayed",
|
"ID": "GameListSortLastPlayed",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "آخر مرة لُعبت",
|
"ar_SA": "آخر مرة لُعبت",
|
||||||
"de_DE": "Zuletzt gespielt",
|
"de_DE": "Zuletzt gespielt",
|
||||||
@ -1623,7 +1748,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "GameListHeaderFileExtension",
|
"ID": "GameListSortFileExtension",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "صيغة الملف",
|
"ar_SA": "صيغة الملف",
|
||||||
"de_DE": "Dateiformat",
|
"de_DE": "Dateiformat",
|
||||||
@ -1648,7 +1773,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "GameListHeaderFileSize",
|
"ID": "GameListSortFileSize",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "حجم الملف",
|
"ar_SA": "حجم الملف",
|
||||||
"de_DE": "Dateigröße",
|
"de_DE": "Dateigröße",
|
||||||
@ -1673,7 +1798,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID": "GameListHeaderPath",
|
"ID": "GameListSortPath",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "المسار",
|
"ar_SA": "المسار",
|
||||||
"de_DE": "Pfad",
|
"de_DE": "Pfad",
|
||||||
@ -1697,6 +1822,106 @@
|
|||||||
"zh_TW": "路徑"
|
"zh_TW": "路徑"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ID": "GameListHeaderCompatibilityStatus",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Compatibility:",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "GameListHeaderTitleId",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Title ID:",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "GameListHeaderHostedGames",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Hosted Games: {0}",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "GameListHeaderPlayerCount",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Online Players: {0}",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ID": "GameListContextMenuOpenUserSaveDirectory",
|
"ID": "GameListContextMenuOpenUserSaveDirectory",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
@ -2522,6 +2747,106 @@
|
|||||||
"zh_TW": "在 macOS 的應用程式資料夾中建立捷徑,啟動選取的應用程式"
|
"zh_TW": "在 macOS 的應用程式資料夾中建立捷徑,啟動選取的應用程式"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ID": "GameListContextMenuShowCompatEntry",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Show Compatibility Entry",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "GameListContextMenuShowCompatEntryToolTip",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Show the selected game in the Compatibility List you can normally access via the Help menu.",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "GameListContextMenuShowGameData",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Show Game Info",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "GameListContextMenuShowGameDataToolTip",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Show stats & details about the currently selected game.",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ID": "GameListContextMenuOpenModsDirectory",
|
"ID": "GameListContextMenuOpenModsDirectory",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
@ -23172,6 +23497,131 @@
|
|||||||
"zh_TW": "無法啟動"
|
"zh_TW": "無法啟動"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ID": "CompatibilityListPlayableTooltip",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Boots and plays without any crashes or GPU bugs of any kind, and at a speed fast enough to reasonably enjoy on an average PC.",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "CompatibilityListIngameTooltip",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Boots and goes in-game but suffers from one or more of the following: crashes, deadlocks, GPU bugs, distractingly bad audio, or is simply too slow. Game still might able to be played all the way through, but not as the game is intended to play.",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "CompatibilityListMenusTooltip",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Boots and goes past the title screen but does not make it into main gameplay.",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "CompatibilityListBootsTooltip",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Boots but does not make it past the title screen.",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "CompatibilityListNothingTooltip",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Does not boot or shows no signs of activity.",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ID": "ExtractAocListHeader",
|
"ID": "ExtractAocListHeader",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
|
@ -33,6 +33,9 @@ namespace Ryujinx.Ava
|
|||||||
.ApplicationLifetime.Cast<IClassicDesktopStyleApplicationLifetime>()
|
.ApplicationLifetime.Cast<IClassicDesktopStyleApplicationLifetime>()
|
||||||
.MainWindow.Cast<MainWindow>();
|
.MainWindow.Cast<MainWindow>();
|
||||||
|
|
||||||
|
public static IClassicDesktopStyleApplicationLifetime AppLifetime => Current!
|
||||||
|
.ApplicationLifetime.Cast<IClassicDesktopStyleApplicationLifetime>();
|
||||||
|
|
||||||
public static bool IsClipboardAvailable(out IClipboard clipboard)
|
public static bool IsClipboardAvailable(out IClipboard clipboard)
|
||||||
{
|
{
|
||||||
clipboard = MainWindow.Clipboard;
|
clipboard = MainWindow.Clipboard;
|
||||||
|
@ -19,6 +19,17 @@
|
|||||||
Header="{ext:Locale GameListContextMenuCreateShortcut}"
|
Header="{ext:Locale GameListContextMenuCreateShortcut}"
|
||||||
Icon="{ext:Icon fa-solid fa-bookmark}"
|
Icon="{ext:Icon fa-solid fa-bookmark}"
|
||||||
ToolTip.Tip="{OnPlatform Default={ext:Locale GameListContextMenuCreateShortcutToolTip}, macOS={ext:Locale GameListContextMenuCreateShortcutToolTipMacOS}}" />
|
ToolTip.Tip="{OnPlatform Default={ext:Locale GameListContextMenuCreateShortcutToolTip}, macOS={ext:Locale GameListContextMenuCreateShortcutToolTipMacOS}}" />
|
||||||
|
<MenuItem
|
||||||
|
IsVisible="{Binding HasCompatibilityEntry}"
|
||||||
|
Click="OpenApplicationCompatibility_Click"
|
||||||
|
Header="{ext:Locale GameListContextMenuShowCompatEntry}"
|
||||||
|
Icon="{ext:Icon mdi-gamepad}"
|
||||||
|
ToolTip.Tip="{ext:Locale GameListContextMenuShowCompatEntryToolTip}"/>
|
||||||
|
<MenuItem
|
||||||
|
Click="OpenApplicationData_Click"
|
||||||
|
Header="{ext:Locale GameListContextMenuShowGameData}"
|
||||||
|
Icon="{ext:Icon mdi-chart-line}"
|
||||||
|
ToolTip.Tip="{ext:Locale GameListContextMenuShowGameDataToolTip}"/>
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Click="OpenUserSaveDirectory_Click"
|
Click="OpenUserSaveDirectory_Click"
|
||||||
@ -74,7 +85,6 @@
|
|||||||
Header="{ext:Locale GameListContextMenuTrimXCI}"
|
Header="{ext:Locale GameListContextMenuTrimXCI}"
|
||||||
IsEnabled="{Binding TrimXCIEnabled}"
|
IsEnabled="{Binding TrimXCIEnabled}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuTrimXCIToolTip}" />
|
ToolTip.Tip="{ext:Locale GameListContextMenuTrimXCIToolTip}" />
|
||||||
<Separator />
|
|
||||||
<MenuItem Header="{ext:Locale GameListContextMenuCacheManagement}" Icon="{ext:Icon mdi-cached}">
|
<MenuItem Header="{ext:Locale GameListContextMenuCacheManagement}" Icon="{ext:Icon mdi-cached}">
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Click="PurgePtcCache_Click"
|
Click="PurgePtcCache_Click"
|
||||||
@ -112,6 +122,7 @@
|
|||||||
Header="{ext:Locale GameListContextMenuExtractDataRomFS}"
|
Header="{ext:Locale GameListContextMenuExtractDataRomFS}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuExtractDataRomFSToolTip}" />
|
ToolTip.Tip="{ext:Locale GameListContextMenuExtractDataRomFSToolTip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
IsVisible="{Binding HasDlc}"
|
||||||
Click="ExtractAocRomFs_Click"
|
Click="ExtractAocRomFs_Click"
|
||||||
Header="{ext:Locale GameListContextMenuExtractDataAocRomFS}"
|
Header="{ext:Locale GameListContextMenuExtractDataAocRomFS}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuExtractDataAocRomFSToolTip}" />
|
ToolTip.Tip="{ext:Locale GameListContextMenuExtractDataAocRomFSToolTip}" />
|
||||||
|
@ -12,6 +12,7 @@ using Ryujinx.Ava.UI.ViewModels;
|
|||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Ava.Utilities;
|
using Ryujinx.Ava.Utilities;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
|
using Ryujinx.Ava.Utilities.Compat;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Helper;
|
using Ryujinx.Common.Helper;
|
||||||
using Ryujinx.HLE.HOS;
|
using Ryujinx.HLE.HOS;
|
||||||
@ -333,7 +334,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
if (sender is not MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
if (sender is not MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DownloadableContentModel selectedDlc = await DlcSelectView.Show(viewModel.SelectedApplication.IdBase, viewModel.ApplicationLibrary);
|
DownloadableContentModel selectedDlc = await DlcSelectView.Show(viewModel.SelectedApplication.Id, viewModel.ApplicationLibrary);
|
||||||
|
|
||||||
if (selectedDlc is not null)
|
if (selectedDlc is not null)
|
||||||
{
|
{
|
||||||
@ -386,6 +387,18 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async void OpenApplicationCompatibility_Click(object sender, RoutedEventArgs args)
|
||||||
|
{
|
||||||
|
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||||
|
await CompatibilityList.Show(viewModel.SelectedApplication.IdString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void OpenApplicationData_Click(object sender, RoutedEventArgs args)
|
||||||
|
{
|
||||||
|
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||||
|
await ApplicationDataView.Show(viewModel.SelectedApplication);
|
||||||
|
}
|
||||||
|
|
||||||
public async void RunApplication_Click(object sender, RoutedEventArgs args)
|
public async void RunApplication_Click(object sender, RoutedEventArgs args)
|
||||||
{
|
{
|
||||||
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||||
@ -394,12 +407,8 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
|
|
||||||
public async void TrimXCI_Click(object sender, RoutedEventArgs args)
|
public async void TrimXCI_Click(object sender, RoutedEventArgs args)
|
||||||
{
|
{
|
||||||
MainWindowViewModel viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
|
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||||
|
|
||||||
if (viewModel?.SelectedApplication != null)
|
|
||||||
{
|
|
||||||
await viewModel.TrimXCIFile(viewModel.SelectedApplication.Path);
|
await viewModel.TrimXCIFile(viewModel.SelectedApplication.Path);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
114
src/Ryujinx/UI/Controls/ApplicationDataView.axaml
Normal file
114
src/Ryujinx/UI/Controls/ApplicationDataView.axaml
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||||
|
xmlns:ext="using:Ryujinx.Ava.Common.Markup"
|
||||||
|
xmlns:viewModels="using:Ryujinx.Ava.UI.ViewModels"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Ryujinx.Ava.UI.Controls.ApplicationDataView"
|
||||||
|
x:DataType="viewModels:ApplicationDataViewModel">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Image Margin="0"
|
||||||
|
MaxWidth="256"
|
||||||
|
MinWidth="256"
|
||||||
|
Source="{Binding AppData.Icon, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
|
||||||
|
<Border Margin="5, 0" Width="1" Height="256" BorderBrush="Gray" Background="Gray" />
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<Grid
|
||||||
|
RowDefinitions="Auto,Auto,Auto"
|
||||||
|
ColumnDefinitions="*">
|
||||||
|
<StackPanel Grid.Row="0">
|
||||||
|
<TextBlock HorizontalAlignment="Left"
|
||||||
|
Text="{Binding FormattedVersion}"
|
||||||
|
TextAlignment="Start"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<TextBlock HorizontalAlignment="Left"
|
||||||
|
Text="{Binding FormattedDeveloper}"
|
||||||
|
TextAlignment="Start"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<TextBlock HorizontalAlignment="Stretch"
|
||||||
|
Text="{Binding FormattedFileExtension}"
|
||||||
|
TextAlignment="Start"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<TextBlock HorizontalAlignment="Stretch"
|
||||||
|
Text="{Binding FormattedFileSize}"
|
||||||
|
TextAlignment="Start"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
</StackPanel>
|
||||||
|
<Separator Grid.Row="1" Margin="0, 10, 0, 10" Height="1" BorderBrush="Gray" Background="Gray" />
|
||||||
|
<StackPanel Grid.Row="2"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Orientation="Vertical"
|
||||||
|
Spacing="5">
|
||||||
|
<StackPanel Orientation="Horizontal" IsVisible="{Binding AppData.HasPlayabilityInfo}">
|
||||||
|
<TextBlock Padding="0, 0, 5, 0" Text="{ext:Locale GameListHeaderCompatibilityStatus}" />
|
||||||
|
<Button
|
||||||
|
Click="PlayabilityStatus_OnClick"
|
||||||
|
HorizontalContentAlignment="Left"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Background="{DynamicResource AppListBackgroundColor}"
|
||||||
|
Padding="0">
|
||||||
|
<TextBlock
|
||||||
|
Margin="1.5"
|
||||||
|
Tag="{Binding AppData.IdString}"
|
||||||
|
Text="{Binding AppData.LocalizedStatus}"
|
||||||
|
Foreground="{Binding AppData.PlayabilityStatus, Converter={x:Static helpers:PlayabilityStatusConverter.Shared}}"
|
||||||
|
ToolTip.Tip="{Binding AppData.LocalizedStatusTooltip}"
|
||||||
|
TextAlignment="Start"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<Button.Styles>
|
||||||
|
<Style Selector="Button">
|
||||||
|
<Setter Property="MinWidth"
|
||||||
|
Value="0" />
|
||||||
|
<!-- avoids very wide buttons from the overall project avalonia style -->
|
||||||
|
</Style>
|
||||||
|
</Button.Styles>
|
||||||
|
</Button>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Padding="0, 0, 5, 0" Text="{ext:Locale GameListHeaderTitleId}" />
|
||||||
|
<Button
|
||||||
|
Click="IdString_OnClick"
|
||||||
|
HorizontalContentAlignment="Left"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Background="{DynamicResource AppListBackgroundColor}"
|
||||||
|
Padding="0">
|
||||||
|
<TextBlock
|
||||||
|
Margin="1.5"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Text="{Binding AppData.IdString}"
|
||||||
|
TextAlignment="Start"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
</Button>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
<Separator Margin="0, 10, 0, 10" Height="1" BorderBrush="Gray" Background="Gray" />
|
||||||
|
<TextBlock
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
IsVisible="{Binding AppData.HasLdnGames}"
|
||||||
|
Text="{Binding FormattedLdnInfo}"
|
||||||
|
TextAlignment="Start"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<Separator IsVisible="{Binding AppData.HasLdnGames}" Margin="0, 10, 0, 10" Height="1" BorderBrush="Gray" Background="Gray" />
|
||||||
|
<StackPanel
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Orientation="Vertical"
|
||||||
|
Spacing="5">
|
||||||
|
<TextBlock
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Text="{Binding FormattedLastPlayed}"
|
||||||
|
TextAlignment="Start"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<TextBlock
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Text="{Binding FormattedPlayTime}"
|
||||||
|
IsVisible="{Binding AppData.HasPlayedPreviously}"
|
||||||
|
TextAlignment="Start"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</UserControl>
|
86
src/Ryujinx/UI/Controls/ApplicationDataView.axaml.cs
Normal file
86
src/Ryujinx/UI/Controls/ApplicationDataView.axaml.cs
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Input.Platform;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
|
using Avalonia.Styling;
|
||||||
|
using FluentAvalonia.UI.Controls;
|
||||||
|
using Ryujinx.Ava;
|
||||||
|
using Ryujinx.Ava.Common.Locale;
|
||||||
|
using Ryujinx.Ava.UI.Controls;
|
||||||
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
|
using Ryujinx.Ava.UI.Windows;
|
||||||
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
|
using Ryujinx.Ava.Utilities.Compat;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.UI.Controls
|
||||||
|
{
|
||||||
|
public partial class ApplicationDataView : UserControl
|
||||||
|
{
|
||||||
|
public static async Task Show(ApplicationData appData)
|
||||||
|
{
|
||||||
|
ContentDialog contentDialog = new()
|
||||||
|
{
|
||||||
|
Title = appData.Name,
|
||||||
|
PrimaryButtonText = string.Empty,
|
||||||
|
SecondaryButtonText = string.Empty,
|
||||||
|
CloseButtonText = LocaleManager.Instance[LocaleKeys.SettingsButtonClose],
|
||||||
|
MinWidth = 256,
|
||||||
|
Content = new ApplicationDataView { DataContext = new ApplicationDataViewModel(appData) }
|
||||||
|
};
|
||||||
|
|
||||||
|
Style closeButton = new(x => x.Name("CloseButton"));
|
||||||
|
closeButton.Setters.Add(new Setter(WidthProperty, 160d));
|
||||||
|
|
||||||
|
Style closeButtonParent = new(x => x.Name("CommandSpace"));
|
||||||
|
closeButtonParent.Setters.Add(new Setter(HorizontalAlignmentProperty,
|
||||||
|
Avalonia.Layout.HorizontalAlignment.Center));
|
||||||
|
|
||||||
|
contentDialog.Styles.Add(closeButton);
|
||||||
|
contentDialog.Styles.Add(closeButtonParent);
|
||||||
|
|
||||||
|
await ContentDialogHelper.ShowAsync(contentDialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApplicationDataView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void PlayabilityStatus_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is not Button { Content: TextBlock playabilityLabel })
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (RyujinxApp.AppLifetime.Windows.TryGetFirst(x => x is ContentDialogOverlayWindow, out Window window))
|
||||||
|
window.Close(ContentDialogResult.None);
|
||||||
|
|
||||||
|
await CompatibilityList.Show((string)playabilityLabel.Tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void IdString_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (DataContext is not MainWindowViewModel mwvm)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (sender is not Button { Content: TextBlock idText })
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!RyujinxApp.IsClipboardAvailable(out IClipboard clipboard))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ApplicationData appData = mwvm.Applications.FirstOrDefault(it => it.IdString == idText.Text);
|
||||||
|
if (appData is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await clipboard.SetTextAsync(appData.IdString);
|
||||||
|
|
||||||
|
NotificationHelper.ShowInformation(
|
||||||
|
"Copied Title ID",
|
||||||
|
$"{appData.Name} ({appData.IdString})");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -86,13 +86,30 @@
|
|||||||
Text="{Binding Version}"
|
Text="{Binding Version}"
|
||||||
TextAlignment="Start"
|
TextAlignment="Start"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
<TextBlock
|
<Button
|
||||||
|
Click="PlayabilityStatus_OnClick"
|
||||||
|
HorizontalContentAlignment="Left"
|
||||||
|
VerticalAlignment="Center"
|
||||||
IsVisible="{Binding HasPlayabilityInfo}"
|
IsVisible="{Binding HasPlayabilityInfo}"
|
||||||
HorizontalAlignment="Stretch"
|
Background="{DynamicResource AppListBackgroundColor}"
|
||||||
Text="{Binding LocalizedStatus}"
|
Margin="-1, 0, 0, 0"
|
||||||
Foreground="{Binding PlayabilityStatus, Converter={x:Static helpers:PlayabilityStatusConverter.Shared}}"
|
Padding="0"
|
||||||
TextAlignment="Start"
|
ToolTip.Tip="{Binding LocalizedStatusTooltip}">
|
||||||
TextWrapping="Wrap" />
|
<TextBlock
|
||||||
|
Margin="1.5"
|
||||||
|
Tag="{Binding IdString}"
|
||||||
|
Text="{Binding LocalizedStatus}"
|
||||||
|
Foreground="{Binding PlayabilityStatus, Converter={x:Static helpers:PlayabilityStatusConverter.Shared}}"
|
||||||
|
TextAlignment="Start"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<Button.Styles>
|
||||||
|
<Style Selector="Button">
|
||||||
|
<Setter Property="MinWidth"
|
||||||
|
Value="0" />
|
||||||
|
<!-- avoids very wide buttons from the overall project avalonia style -->
|
||||||
|
</Style>
|
||||||
|
</Button.Styles>
|
||||||
|
</Button>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
<StackPanel
|
<StackPanel
|
||||||
@ -124,7 +141,8 @@
|
|||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
Text="{Binding Converter={helpers:MultiplayerInfoConverter}}"
|
IsVisible="{Binding HasLdnGames}"
|
||||||
|
Text="{Binding Converter={x:Static helpers:MultiplayerInfoConverter.Instance}}"
|
||||||
TextAlignment="Start"
|
TextAlignment="Start"
|
||||||
TextWrapping="Wrap"/>
|
TextWrapping="Wrap"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -5,7 +5,9 @@ using Avalonia.Interactivity;
|
|||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
|
using Ryujinx.Ava.Utilities.Compat;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Controls
|
namespace Ryujinx.Ava.UI.Controls
|
||||||
@ -29,6 +31,17 @@ namespace Ryujinx.Ava.UI.Controls
|
|||||||
RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent));
|
RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void PlayabilityStatus_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (DataContext is not MainWindowViewModel mwvm)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (sender is not Button { Content: TextBlock playabilityLabel })
|
||||||
|
return;
|
||||||
|
|
||||||
|
await CompatibilityList.Show((string)playabilityLabel.Tag);
|
||||||
|
}
|
||||||
|
|
||||||
private async void IdString_OnClick(object sender, RoutedEventArgs e)
|
private async void IdString_OnClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (DataContext is not MainWindowViewModel mwvm)
|
if (DataContext is not MainWindowViewModel mwvm)
|
||||||
|
@ -1,27 +1,31 @@
|
|||||||
using Avalonia.Data.Converters;
|
using Avalonia.Data.Converters;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Gommon;
|
||||||
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Helpers
|
namespace Ryujinx.Ava.UI.Helpers
|
||||||
{
|
{
|
||||||
internal class MultiplayerInfoConverter : MarkupExtension, IValueConverter
|
internal class MultiplayerInfoConverter : MarkupExtension, IValueConverter
|
||||||
{
|
{
|
||||||
private static readonly MultiplayerInfoConverter _instance = new();
|
public static readonly MultiplayerInfoConverter Instance = new();
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (value is ApplicationData applicationData)
|
if (value is not ApplicationData { HasLdnGames: true } applicationData)
|
||||||
{
|
return "";
|
||||||
if (applicationData.PlayerCount != 0 && applicationData.GameCount != 0)
|
|
||||||
{
|
|
||||||
return $"Hosted Games: {applicationData.GameCount}\nOnline Players: {applicationData.PlayerCount}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
|
|
||||||
|
return new StringBuilder()
|
||||||
|
.AppendLine(
|
||||||
|
LocaleManager.Instance[LocaleKeys.GameListHeaderHostedGames]
|
||||||
|
.Format(applicationData.GameCount))
|
||||||
|
.Append(
|
||||||
|
LocaleManager.Instance[LocaleKeys.GameListHeaderPlayerCount]
|
||||||
|
.Format(applicationData.PlayerCount))
|
||||||
|
.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
@ -31,7 +35,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||||||
|
|
||||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
return _instance;
|
return Instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
26
src/Ryujinx/UI/ViewModels/ApplicationDataViewModel.cs
Normal file
26
src/Ryujinx/UI/ViewModels/ApplicationDataViewModel.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using Gommon;
|
||||||
|
using Ryujinx.Ava.Common.Locale;
|
||||||
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
|
{
|
||||||
|
public class ApplicationDataViewModel : BaseModel
|
||||||
|
{
|
||||||
|
public ApplicationData AppData { get; }
|
||||||
|
|
||||||
|
public ApplicationDataViewModel(ApplicationData appData) => AppData = appData;
|
||||||
|
|
||||||
|
public string FormattedVersion => LocaleManager.Instance[LocaleKeys.GameListHeaderVersion].Format(AppData.Version);
|
||||||
|
public string FormattedDeveloper => LocaleManager.Instance[LocaleKeys.GameListHeaderDeveloper].Format(AppData.Developer);
|
||||||
|
|
||||||
|
public string FormattedFileExtension => LocaleManager.Instance[LocaleKeys.GameListHeaderFileExtension].Format(AppData.FileExtension);
|
||||||
|
public string FormattedLastPlayed => LocaleManager.Instance[LocaleKeys.GameListHeaderLastPlayed].Format(AppData.LastPlayedString);
|
||||||
|
public string FormattedPlayTime => LocaleManager.Instance[LocaleKeys.GameListHeaderTimePlayed].Format(AppData.TimePlayedString);
|
||||||
|
public string FormattedFileSize => LocaleManager.Instance[LocaleKeys.GameListHeaderFileSize].Format(AppData.FileSizeString);
|
||||||
|
|
||||||
|
public string FormattedLdnInfo =>
|
||||||
|
$"{LocaleManager.Instance[LocaleKeys.GameListHeaderHostedGames].Format(AppData.GameCount)}" +
|
||||||
|
$"\n" +
|
||||||
|
$"{LocaleManager.Instance[LocaleKeys.GameListHeaderPlayerCount].Format(AppData.PlayerCount)}";
|
||||||
|
}
|
||||||
|
}
|
@ -14,9 +14,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
public DlcSelectViewModel(ulong titleId, ApplicationLibrary appLibrary)
|
public DlcSelectViewModel(ulong titleId, ApplicationLibrary appLibrary)
|
||||||
{
|
{
|
||||||
_dlcs = appLibrary.DownloadableContents.Items
|
_dlcs = appLibrary.FindDlcsFor(titleId)
|
||||||
.Where(x => x.Dlc.TitleIdBase == titleId)
|
|
||||||
.Select(x => x.Dlc)
|
|
||||||
.OrderBy(it => it.IsBundled ? 0 : 1)
|
.OrderBy(it => it.IsBundled ? 0 : 1)
|
||||||
.ThenBy(it => it.TitleId)
|
.ThenBy(it => it.TitleId)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
@ -69,8 +69,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
private void LoadDownloadableContents()
|
private void LoadDownloadableContents()
|
||||||
{
|
{
|
||||||
IEnumerable<(DownloadableContentModel Dlc, bool IsEnabled)> dlcs = _applicationLibrary.DownloadableContents.Items
|
(DownloadableContentModel Dlc, bool IsEnabled)[] dlcs = _applicationLibrary.FindDlcConfigurationFor(_applicationData.Id);
|
||||||
.Where(it => it.Dlc.TitleIdBase == _applicationData.IdBase);
|
|
||||||
|
|
||||||
bool hasBundledContent = false;
|
bool hasBundledContent = false;
|
||||||
foreach ((DownloadableContentModel dlc, bool isEnabled) in dlcs)
|
foreach ((DownloadableContentModel dlc, bool isEnabled) in dlcs)
|
||||||
|
@ -349,6 +349,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasCompatibilityEntry => SelectedApplication.HasPlayabilityInfo;
|
||||||
|
|
||||||
|
public bool HasDlc => ApplicationLibrary.HasDlcs(SelectedApplication.Id);
|
||||||
|
|
||||||
public bool OpenUserSaveDirectoryEnabled => SelectedApplication.HasControlHolder && SelectedApplication.ControlHolder.Value.UserAccountSaveDataSize > 0;
|
public bool OpenUserSaveDirectoryEnabled => SelectedApplication.HasControlHolder && SelectedApplication.ControlHolder.Value.UserAccountSaveDataSize > 0;
|
||||||
|
|
||||||
public bool OpenDeviceSaveDirectoryEnabled => SelectedApplication.HasControlHolder && SelectedApplication.ControlHolder.Value.DeviceSaveDataSize > 0;
|
public bool OpenDeviceSaveDirectoryEnabled => SelectedApplication.HasControlHolder && SelectedApplication.ControlHolder.Value.DeviceSaveDataSize > 0;
|
||||||
@ -629,15 +633,15 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
{
|
{
|
||||||
return SortMode switch
|
return SortMode switch
|
||||||
{
|
{
|
||||||
ApplicationSort.Title => LocaleManager.Instance[LocaleKeys.GameListHeaderApplication],
|
|
||||||
ApplicationSort.Developer => LocaleManager.Instance[LocaleKeys.GameListHeaderDeveloper],
|
|
||||||
ApplicationSort.LastPlayed => LocaleManager.Instance[LocaleKeys.GameListHeaderLastPlayed],
|
|
||||||
ApplicationSort.TotalTimePlayed => LocaleManager.Instance[LocaleKeys.GameListHeaderTimePlayed],
|
|
||||||
ApplicationSort.FileType => LocaleManager.Instance[LocaleKeys.GameListHeaderFileExtension],
|
|
||||||
ApplicationSort.FileSize => LocaleManager.Instance[LocaleKeys.GameListHeaderFileSize],
|
|
||||||
ApplicationSort.Path => LocaleManager.Instance[LocaleKeys.GameListHeaderPath],
|
|
||||||
ApplicationSort.Favorite => LocaleManager.Instance[LocaleKeys.CommonFavorite],
|
ApplicationSort.Favorite => LocaleManager.Instance[LocaleKeys.CommonFavorite],
|
||||||
ApplicationSort.TitleId => LocaleManager.Instance[LocaleKeys.DlcManagerTableHeadingTitleIdLabel],
|
ApplicationSort.TitleId => LocaleManager.Instance[LocaleKeys.DlcManagerTableHeadingTitleIdLabel],
|
||||||
|
ApplicationSort.Title => LocaleManager.Instance[LocaleKeys.GameListHeaderApplication],
|
||||||
|
ApplicationSort.Developer => LocaleManager.Instance[LocaleKeys.GameListSortDeveloper],
|
||||||
|
ApplicationSort.LastPlayed => LocaleManager.Instance[LocaleKeys.GameListSortLastPlayed],
|
||||||
|
ApplicationSort.TotalTimePlayed => LocaleManager.Instance[LocaleKeys.GameListSortTimePlayed],
|
||||||
|
ApplicationSort.FileType => LocaleManager.Instance[LocaleKeys.GameListSortFileExtension],
|
||||||
|
ApplicationSort.FileSize => LocaleManager.Instance[LocaleKeys.GameListSortFileSize],
|
||||||
|
ApplicationSort.Path => LocaleManager.Instance[LocaleKeys.GameListSortPath],
|
||||||
_ => string.Empty,
|
_ => string.Empty,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
private void LoadUpdates()
|
private void LoadUpdates()
|
||||||
{
|
{
|
||||||
IEnumerable<(TitleUpdateModel TitleUpdate, bool IsSelected)> updates = ApplicationLibrary.TitleUpdates.Items
|
(TitleUpdateModel TitleUpdate, bool IsSelected)[] updates = ApplicationLibrary.FindUpdateConfigurationFor(ApplicationData.Id);
|
||||||
.Where(it => it.TitleUpdate.TitleIdBase == ApplicationData.IdBase);
|
|
||||||
|
|
||||||
bool hasBundledContent = false;
|
bool hasBundledContent = false;
|
||||||
SelectedUpdate = new TitleUpdateViewModelNoUpdate();
|
SelectedUpdate = new TitleUpdateViewModelNoUpdate();
|
||||||
|
@ -50,7 +50,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
UninstallFileTypesMenuItem.Command = Commands.Create(UninstallFileTypes);
|
UninstallFileTypesMenuItem.Command = Commands.Create(UninstallFileTypes);
|
||||||
XciTrimmerMenuItem.Command = Commands.Create(XCITrimmerWindow.Show);
|
XciTrimmerMenuItem.Command = Commands.Create(XCITrimmerWindow.Show);
|
||||||
AboutWindowMenuItem.Command = Commands.Create(AboutWindow.Show);
|
AboutWindowMenuItem.Command = Commands.Create(AboutWindow.Show);
|
||||||
CompatibilityListMenuItem.Command = Commands.Create(CompatibilityList.Show);
|
CompatibilityListMenuItem.Command = Commands.Create(() => CompatibilityList.Show());
|
||||||
|
|
||||||
UpdateMenuItem.Command = Commands.Create(async () =>
|
UpdateMenuItem.Command = Commands.Create(async () =>
|
||||||
{
|
{
|
||||||
|
@ -113,37 +113,37 @@
|
|||||||
Tag="TitleId" />
|
Tag="TitleId" />
|
||||||
<RadioButton
|
<RadioButton
|
||||||
Checked="Sort_Checked"
|
Checked="Sort_Checked"
|
||||||
Content="{ext:Locale GameListHeaderDeveloper}"
|
Content="{ext:Locale GameListSortDeveloper}"
|
||||||
GroupName="Sort"
|
GroupName="Sort"
|
||||||
IsChecked="{Binding IsSortedByDeveloper, Mode=OneTime}"
|
IsChecked="{Binding IsSortedByDeveloper, Mode=OneTime}"
|
||||||
Tag="Developer" />
|
Tag="Developer" />
|
||||||
<RadioButton
|
<RadioButton
|
||||||
Checked="Sort_Checked"
|
Checked="Sort_Checked"
|
||||||
Content="{ext:Locale GameListHeaderTimePlayed}"
|
Content="{ext:Locale GameListSortTimePlayed}"
|
||||||
GroupName="Sort"
|
GroupName="Sort"
|
||||||
IsChecked="{Binding IsSortedByTimePlayed, Mode=OneTime}"
|
IsChecked="{Binding IsSortedByTimePlayed, Mode=OneTime}"
|
||||||
Tag="TotalTimePlayed" />
|
Tag="TotalTimePlayed" />
|
||||||
<RadioButton
|
<RadioButton
|
||||||
Checked="Sort_Checked"
|
Checked="Sort_Checked"
|
||||||
Content="{ext:Locale GameListHeaderLastPlayed}"
|
Content="{ext:Locale GameListSortLastPlayed}"
|
||||||
GroupName="Sort"
|
GroupName="Sort"
|
||||||
IsChecked="{Binding IsSortedByLastPlayed, Mode=OneTime}"
|
IsChecked="{Binding IsSortedByLastPlayed, Mode=OneTime}"
|
||||||
Tag="LastPlayed" />
|
Tag="LastPlayed" />
|
||||||
<RadioButton
|
<RadioButton
|
||||||
Checked="Sort_Checked"
|
Checked="Sort_Checked"
|
||||||
Content="{ext:Locale GameListHeaderFileExtension}"
|
Content="{ext:Locale GameListSortFileExtension}"
|
||||||
GroupName="Sort"
|
GroupName="Sort"
|
||||||
IsChecked="{Binding IsSortedByType, Mode=OneTime}"
|
IsChecked="{Binding IsSortedByType, Mode=OneTime}"
|
||||||
Tag="FileType" />
|
Tag="FileType" />
|
||||||
<RadioButton
|
<RadioButton
|
||||||
Checked="Sort_Checked"
|
Checked="Sort_Checked"
|
||||||
Content="{ext:Locale GameListHeaderFileSize}"
|
Content="{ext:Locale GameListSortFileSize}"
|
||||||
GroupName="Sort"
|
GroupName="Sort"
|
||||||
IsChecked="{Binding IsSortedBySize, Mode=OneTime}"
|
IsChecked="{Binding IsSortedBySize, Mode=OneTime}"
|
||||||
Tag="FileSize" />
|
Tag="FileSize" />
|
||||||
<RadioButton
|
<RadioButton
|
||||||
Checked="Sort_Checked"
|
Checked="Sort_Checked"
|
||||||
Content="{ext:Locale GameListHeaderPath}"
|
Content="{ext:Locale GameListSortPath}"
|
||||||
GroupName="Sort"
|
GroupName="Sort"
|
||||||
IsChecked="{Binding IsSortedByPath, Mode=OneTime}"
|
IsChecked="{Binding IsSortedByPath, Mode=OneTime}"
|
||||||
Tag="Path" />
|
Tag="Path" />
|
||||||
|
@ -46,9 +46,24 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
: string.Empty;
|
: string.Empty;
|
||||||
|
|
||||||
public LocaleKeys? PlayabilityStatus { get; set; }
|
public LocaleKeys? PlayabilityStatus { get; set; }
|
||||||
|
public string LocalizedStatusTooltip =>
|
||||||
|
PlayabilityStatus.HasValue
|
||||||
|
#pragma warning disable CS8509 // It is exhaustive for any value this property can contain.
|
||||||
|
? LocaleManager.Instance[PlayabilityStatus!.Value switch
|
||||||
|
#pragma warning restore CS8509
|
||||||
|
{
|
||||||
|
LocaleKeys.CompatibilityListPlayable => LocaleKeys.CompatibilityListPlayableTooltip,
|
||||||
|
LocaleKeys.CompatibilityListIngame => LocaleKeys.CompatibilityListIngameTooltip,
|
||||||
|
LocaleKeys.CompatibilityListMenus => LocaleKeys.CompatibilityListMenusTooltip,
|
||||||
|
LocaleKeys.CompatibilityListBoots => LocaleKeys.CompatibilityListBootsTooltip,
|
||||||
|
LocaleKeys.CompatibilityListNothing => LocaleKeys.CompatibilityListNothingTooltip,
|
||||||
|
}]
|
||||||
|
: string.Empty;
|
||||||
public int PlayerCount { get; set; }
|
public int PlayerCount { get; set; }
|
||||||
public int GameCount { get; set; }
|
public int GameCount { get; set; }
|
||||||
|
|
||||||
|
public bool HasLdnGames => PlayerCount != 0 && GameCount != 0;
|
||||||
|
|
||||||
public TimeSpan TimePlayed { get; set; }
|
public TimeSpan TimePlayed { get; set; }
|
||||||
public DateTime? LastPlayed { get; set; }
|
public DateTime? LastPlayed { get; set; }
|
||||||
public string FileExtension { get; set; }
|
public string FileExtension { get; set; }
|
||||||
|
@ -129,12 +129,49 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
if (appData.HasValue)
|
if (appData.HasValue)
|
||||||
return appData.Value.Name;
|
return appData.Value.Name;
|
||||||
|
|
||||||
if (DownloadableContents.Keys.FindFirst(x => x.TitleId == id).TryGet(out DownloadableContentModel dlcData))
|
if (!DownloadableContents.Keys.FindFirst(x => x.TitleId == id).TryGet(out DownloadableContentModel dlcData))
|
||||||
return Path.GetFileNameWithoutExtension(dlcData.FileName);
|
return id.ToString("X16");
|
||||||
|
|
||||||
return id.ToString("X16");
|
string name = Path.GetFileNameWithoutExtension(dlcData.FileName)!;
|
||||||
|
int idx = name.IndexOf('[');
|
||||||
|
if (idx != -1)
|
||||||
|
name = name[..idx];
|
||||||
|
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool FindApplication(ulong id, out ApplicationData foundData)
|
||||||
|
{
|
||||||
|
DynamicData.Kernel.Optional<ApplicationData> appData = Applications.Lookup(id);
|
||||||
|
foundData = appData.HasValue ? appData.Value : null;
|
||||||
|
|
||||||
|
return appData.HasValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool FindUpdate(ulong id, out TitleUpdateModel foundData)
|
||||||
|
{
|
||||||
|
Gommon.Optional<TitleUpdateModel> appData =
|
||||||
|
TitleUpdates.Keys.FindFirst(x => x.TitleId == id);
|
||||||
|
foundData = appData.HasValue ? appData.Value : null;
|
||||||
|
|
||||||
|
return appData.HasValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TitleUpdateModel[] FindUpdatesFor(ulong id)
|
||||||
|
=> TitleUpdates.Keys.Where(x => x.TitleIdBase == (id & ~0x1FFFUL)).ToArray();
|
||||||
|
|
||||||
|
public (TitleUpdateModel TitleUpdate, bool IsSelected)[] FindUpdateConfigurationFor(ulong id)
|
||||||
|
=> TitleUpdates.Items.Where(x => x.TitleUpdate.TitleIdBase == (id & ~0x1FFFUL)).ToArray();
|
||||||
|
|
||||||
|
public DownloadableContentModel[] FindDlcsFor(ulong id)
|
||||||
|
=> DownloadableContents.Keys.Where(x => x.TitleIdBase == (id & ~0x1FFFUL)).ToArray();
|
||||||
|
|
||||||
|
public (DownloadableContentModel Dlc, bool IsEnabled)[] FindDlcConfigurationFor(ulong id)
|
||||||
|
=> DownloadableContents.Items.Where(x => x.Dlc.TitleIdBase == (id & ~0x1FFFUL)).ToArray();
|
||||||
|
|
||||||
|
public bool HasDlcs(ulong id)
|
||||||
|
=> DownloadableContents.Keys.Any(x => x.TitleIdBase == (id & ~0x1FFFUL));
|
||||||
|
|
||||||
/// <exception cref="LibHac.Common.Keys.MissingKeyException">The configured key set is missing a key.</exception>
|
/// <exception cref="LibHac.Common.Keys.MissingKeyException">The configured key set is missing a key.</exception>
|
||||||
/// <exception cref="InvalidDataException">The NCA header could not be decrypted.</exception>
|
/// <exception cref="InvalidDataException">The NCA header could not be decrypted.</exception>
|
||||||
/// <exception cref="NotSupportedException">The NCA version is not supported.</exception>
|
/// <exception cref="NotSupportedException">The NCA version is not supported.</exception>
|
||||||
|
@ -100,12 +100,25 @@ namespace Ryujinx.Ava.Utilities.Compat
|
|||||||
public Optional<string> TitleId { get; }
|
public Optional<string> TitleId { get; }
|
||||||
public string[] Labels { get; }
|
public string[] Labels { get; }
|
||||||
public LocaleKeys? Status { get; }
|
public LocaleKeys? Status { get; }
|
||||||
|
|
||||||
|
public LocaleKeys? StatusDescription
|
||||||
|
=> Status switch
|
||||||
|
{
|
||||||
|
LocaleKeys.CompatibilityListPlayable => LocaleKeys.CompatibilityListPlayableTooltip,
|
||||||
|
LocaleKeys.CompatibilityListIngame => LocaleKeys.CompatibilityListIngameTooltip,
|
||||||
|
LocaleKeys.CompatibilityListMenus => LocaleKeys.CompatibilityListMenusTooltip,
|
||||||
|
LocaleKeys.CompatibilityListBoots => LocaleKeys.CompatibilityListBootsTooltip,
|
||||||
|
LocaleKeys.CompatibilityListNothing => LocaleKeys.CompatibilityListNothingTooltip,
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
|
||||||
public DateTime LastUpdated { get; }
|
public DateTime LastUpdated { get; }
|
||||||
|
|
||||||
public string LocalizedLastUpdated =>
|
public string LocalizedLastUpdated =>
|
||||||
LocaleManager.FormatDynamicValue(LocaleKeys.CompatibilityListLastUpdated, LastUpdated.Humanize());
|
LocaleManager.FormatDynamicValue(LocaleKeys.CompatibilityListLastUpdated, LastUpdated.Humanize());
|
||||||
|
|
||||||
public string LocalizedStatus => LocaleManager.Instance[Status!.Value];
|
public string LocalizedStatus => LocaleManager.Instance[Status!.Value];
|
||||||
|
public string LocalizedStatusDescription => LocaleManager.Instance[StatusDescription!.Value];
|
||||||
public string FormattedTitleId => TitleId
|
public string FormattedTitleId => TitleId
|
||||||
.OrElse(new string(' ', 16));
|
.OrElse(new string(' ', 16));
|
||||||
|
|
||||||
@ -113,20 +126,17 @@ namespace Ryujinx.Ava.Utilities.Compat
|
|||||||
.Select(FormatLabelName)
|
.Select(FormatLabelName)
|
||||||
.JoinToString(", ");
|
.JoinToString(", ");
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString() =>
|
||||||
{
|
new StringBuilder("CompatibilityEntry: {")
|
||||||
StringBuilder sb = new("CompatibilityEntry: {");
|
.Append($"{nameof(GameName)}=\"{GameName}\", ")
|
||||||
sb.Append($"{nameof(GameName)}=\"{GameName}\", ");
|
.Append($"{nameof(TitleId)}={TitleId}, ")
|
||||||
sb.Append($"{nameof(TitleId)}={TitleId}, ");
|
.Append($"{nameof(Labels)}={
|
||||||
sb.Append($"{nameof(Labels)}={
|
Labels.FormatCollection(it => $"\"{it}\"", separator: ", ", prefix: "[", suffix: "]")
|
||||||
Labels.FormatCollection(it => $"\"{it}\"", separator: ", ", prefix: "[", suffix: "]")
|
}, ")
|
||||||
}, ");
|
.Append($"{nameof(Status)}=\"{Status}\", ")
|
||||||
sb.Append($"{nameof(Status)}=\"{Status}\", ");
|
.Append($"{nameof(LastUpdated)}=\"{LastUpdated}\"")
|
||||||
sb.Append($"{nameof(LastUpdated)}=\"{LastUpdated}\"");
|
.Append('}')
|
||||||
sb.Append('}');
|
.ToString();
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string FormatLabelName(string labelName) => labelName.ToLower() switch
|
public static string FormatLabelName(string labelName) => labelName.ToLower() switch
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
Text="{ext:Locale CompatibilityListWarning}" />
|
Text="{ext:Locale CompatibilityListWarning}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid Grid.Row="1" ColumnDefinitions="*,Auto,Auto">
|
<Grid Grid.Row="1" ColumnDefinitions="*,Auto,Auto">
|
||||||
<TextBox Grid.Column="0" HorizontalAlignment="Stretch" Watermark="{ext:Locale CompatibilityListSearchBoxWatermark}" TextChanged="TextBox_OnTextChanged" />
|
<TextBox Name="SearchBox" Grid.Column="0" HorizontalAlignment="Stretch" Watermark="{ext:Locale CompatibilityListSearchBoxWatermark}" TextChanged="TextBox_OnTextChanged" />
|
||||||
<CheckBox Grid.Column="1" Margin="7, 0, 0, 0" IsChecked="{Binding OnlyShowOwnedGames}" />
|
<CheckBox Grid.Column="1" Margin="7, 0, 0, 0" IsChecked="{Binding OnlyShowOwnedGames}" />
|
||||||
<TextBlock Grid.Column="2" Margin="-10, 0, 0, 0" Text="{ext:Locale CompatibilityListOnlyShowOwnedGames}" />
|
<TextBlock Grid.Column="2" Margin="-10, 0, 0, 0" Text="{ext:Locale CompatibilityListOnlyShowOwnedGames}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -64,6 +64,8 @@
|
|||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{Binding LocalizedStatus}"
|
Text="{Binding LocalizedStatus}"
|
||||||
Width="85"
|
Width="85"
|
||||||
|
Background="Transparent"
|
||||||
|
ToolTip.Tip="{Binding LocalizedStatusDescription}"
|
||||||
Foreground="{Binding Status, Converter={x:Static helpers:PlayabilityStatusConverter.Shared}}"
|
Foreground="{Binding Status, Converter={x:Static helpers:PlayabilityStatusConverter.Shared}}"
|
||||||
TextWrapping="NoWrap" />
|
TextWrapping="NoWrap" />
|
||||||
<TextBlock Grid.Column="3"
|
<TextBlock Grid.Column="3"
|
||||||
|
@ -9,7 +9,7 @@ namespace Ryujinx.Ava.Utilities.Compat
|
|||||||
{
|
{
|
||||||
public partial class CompatibilityList : UserControl
|
public partial class CompatibilityList : UserControl
|
||||||
{
|
{
|
||||||
public static async Task Show()
|
public static async Task Show(string titleId = null)
|
||||||
{
|
{
|
||||||
ContentDialog contentDialog = new()
|
ContentDialog contentDialog = new()
|
||||||
{
|
{
|
||||||
@ -18,7 +18,10 @@ namespace Ryujinx.Ava.Utilities.Compat
|
|||||||
CloseButtonText = LocaleManager.Instance[LocaleKeys.SettingsButtonClose],
|
CloseButtonText = LocaleManager.Instance[LocaleKeys.SettingsButtonClose],
|
||||||
Content = new CompatibilityList
|
Content = new CompatibilityList
|
||||||
{
|
{
|
||||||
DataContext = new CompatibilityViewModel(RyujinxApp.MainWindow.ViewModel.ApplicationLibrary)
|
DataContext = new CompatibilityViewModel(RyujinxApp.MainWindow.ViewModel.ApplicationLibrary),
|
||||||
|
SearchBox = {
|
||||||
|
Text = titleId ?? ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user