Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
62f8ceb60b | |||
1a888ae087 | |||
84d0ca5645 | |||
31b8d413d5 | |||
6e02cac952 | |||
3a3380fa25 |
@ -55,7 +55,6 @@ namespace Ryujinx.Ava
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
var result = await ContentDialogHelper.CreateConfirmationDialog(
|
||||
(desktop.MainWindow as MainWindow).SettingsWindow,
|
||||
LocaleManager.Instance["DialogThemeRestartMessage"],
|
||||
LocaleManager.Instance["DialogThemeRestartSubMessage"],
|
||||
LocaleManager.Instance["InputDialogYes"],
|
||||
|
@ -53,6 +53,7 @@ namespace Ryujinx.Ava
|
||||
internal class AppHost
|
||||
{
|
||||
private const int CursorHideIdleTime = 8; // Hide Cursor seconds
|
||||
private const float MaxResolutionScale = 4.0f; // Max resolution hotkeys can scale to before wrapping.
|
||||
|
||||
private static readonly Cursor InvisibleCursor = new Cursor(StandardCursorType.None);
|
||||
|
||||
@ -417,10 +418,12 @@ namespace Ryujinx.Ava
|
||||
{
|
||||
if (userError == UserError.NoFirmware)
|
||||
{
|
||||
string message = string.Format(LocaleManager.Instance["DialogFirmwareInstallEmbeddedMessage"], firmwareVersion.VersionString);
|
||||
string message = string.Format(LocaleManager.Instance["DialogFirmwareInstallEmbeddedMessage"],
|
||||
firmwareVersion.VersionString);
|
||||
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(_parent,
|
||||
LocaleManager.Instance["DialogFirmwareNoFirmwareInstalledMessage"], message, LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], "");
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
|
||||
LocaleManager.Instance["DialogFirmwareNoFirmwareInstalledMessage"], message,
|
||||
LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], "");
|
||||
|
||||
if (result != UserResult.Yes)
|
||||
{
|
||||
@ -450,7 +453,7 @@ namespace Ryujinx.Ava
|
||||
|
||||
string message = string.Format(LocaleManager.Instance["DialogFirmwareInstallEmbeddedSuccessMessage"], firmwareVersion.VersionString);
|
||||
|
||||
await ContentDialogHelper.CreateInfoDialog(_parent,
|
||||
await ContentDialogHelper.CreateInfoDialog(
|
||||
string.Format(LocaleManager.Instance["DialogFirmwareInstalledMessage"], firmwareVersion.VersionString),
|
||||
message,
|
||||
LocaleManager.Instance["InputDialogOk"],
|
||||
@ -879,7 +882,7 @@ namespace Ryujinx.Ava
|
||||
}
|
||||
|
||||
_dialogShown = true;
|
||||
shouldExit = await ContentDialogHelper.CreateStopEmulationDialog(_parent);
|
||||
shouldExit = await ContentDialogHelper.CreateStopEmulationDialog();
|
||||
|
||||
_dialogShown = false;
|
||||
}
|
||||
@ -974,6 +977,13 @@ namespace Ryujinx.Ava
|
||||
|
||||
_parent.ViewModel.Volume = Device.GetVolume();
|
||||
break;
|
||||
case KeyboardHotkeyState.ResScaleUp:
|
||||
GraphicsConfig.ResScale = GraphicsConfig.ResScale % MaxResolutionScale + 1;
|
||||
break;
|
||||
case KeyboardHotkeyState.ResScaleDown:
|
||||
GraphicsConfig.ResScale =
|
||||
(MaxResolutionScale + GraphicsConfig.ResScale - 2) % MaxResolutionScale + 1;
|
||||
break;
|
||||
case KeyboardHotkeyState.None:
|
||||
(_keyboardInterface as AvaloniaKeyboard).Clear();
|
||||
break;
|
||||
@ -1031,6 +1041,14 @@ namespace Ryujinx.Ava
|
||||
{
|
||||
state = KeyboardHotkeyState.ToggleMute;
|
||||
}
|
||||
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ResScaleUp))
|
||||
{
|
||||
state = KeyboardHotkeyState.ResScaleUp;
|
||||
}
|
||||
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ResScaleDown))
|
||||
{
|
||||
state = KeyboardHotkeyState.ResScaleDown;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
@ -556,5 +556,7 @@
|
||||
"SettingsSelectThemeFileDialogTitle" : "Wähle ein benutzerdefiniertes Thema",
|
||||
"SettingsXamlThemeFile" : "Xaml Thema-Datei",
|
||||
"SettingsTabGraphicsBackend" : "Grafik-Backend",
|
||||
"GraphicsBackendTooltip" : "Ändert das Grafik-Backend"
|
||||
"GraphicsBackendTooltip" : "Ändert das Grafik-Backend",
|
||||
"SettingsTabHotkeysResScaleUpHotkey": "Auflösung erhöhen:",
|
||||
"SettingsTabHotkeysResScaleDownHotkey": "Auflösung vermindern:"
|
||||
}
|
||||
|
@ -256,8 +256,8 @@
|
||||
"UserProfilesSaveProfileName": "Save Profile Name",
|
||||
"UserProfilesChangeProfileImage": "Change Profile Image",
|
||||
"UserProfilesAvailableUserProfiles": "Available User Profiles:",
|
||||
"UserProfilesAddNewProfile": "Add New Profile",
|
||||
"UserProfilesDeleteSelectedProfile": "Delete Selected Profile",
|
||||
"UserProfilesAddNewProfile": "Create Profile",
|
||||
"UserProfilesDeleteSelectedProfile": "Delete Selected",
|
||||
"UserProfilesClose": "Close",
|
||||
"ProfileImageSelectionTitle": "Profile Image Selection",
|
||||
"ProfileImageSelectionHeader": "Choose a profile Image",
|
||||
@ -568,5 +568,14 @@
|
||||
"UpdateWindowTitle": "Manage Game Updates",
|
||||
"CheatWindowHeading": "Cheats Available for {0} [{1}]",
|
||||
"DlcWindowHeading": "DLC Available for {0} [{1}]",
|
||||
"GameUpdateWindowHeading": "Updates Available for {0} [{1}]"
|
||||
"UserProfilesEditProfile": "Edit Selected",
|
||||
"Cancel": "Cancel",
|
||||
"Save": "Save",
|
||||
"Discard": "Discard",
|
||||
"UserProfilesSetProfileImage": "Set Profile Image",
|
||||
"UserProfileEmptyNameError": "Name is required",
|
||||
"UserProfileNoImageError": "Profile image must be set",
|
||||
"GameUpdateWindowHeading": "Updates Available for {0} [{1}]",
|
||||
"SettingsTabHotkeysResScaleUpHotkey": "Increase resolution:",
|
||||
"SettingsTabHotkeysResScaleDownHotkey": "Decrease resolution:"
|
||||
}
|
||||
|
@ -568,5 +568,7 @@
|
||||
"UpdateWindowTitle": "Administrar actualizaciones",
|
||||
"CheatWindowHeading": "Cheats disponibles para {0} [{1}]",
|
||||
"DlcWindowHeading": "Contenido descargable disponible para {0} [{1}]",
|
||||
"GameUpdateWindowHeading": "Actualizaciones disponibles para {0} [{1}]"
|
||||
"GameUpdateWindowHeading": "Actualizaciones disponibles para {0} [{1}]",
|
||||
"SettingsTabHotkeysResScaleUpHotkey": "Aumentar la resolución:",
|
||||
"SettingsTabHotkeysResScaleDownHotkey": "Disminuir la resolución:"
|
||||
}
|
||||
|
@ -554,5 +554,7 @@
|
||||
"ControllerMotionTitle": "Impostazioni dei sensori di movimento",
|
||||
"ControllerRumbleTitle": "Impostazioni di vibrazione",
|
||||
"SettingsSelectThemeFileDialogTitle" : "Seleziona file del tema",
|
||||
"SettingsXamlThemeFile" : "File del tema xaml"
|
||||
"SettingsXamlThemeFile" : "File del tema xaml",
|
||||
"SettingsTabHotkeysResScaleUpHotkey": "Aumentare la risoluzione:",
|
||||
"SettingsTabHotkeysResScaleDownHotkey": "Diminuire la risoluzione:"
|
||||
}
|
||||
|
@ -554,5 +554,7 @@
|
||||
"ControllerMotionTitle": "Configurações do controle de movimento",
|
||||
"ControllerRumbleTitle": "Configurações de vibração",
|
||||
"SettingsSelectThemeFileDialogTitle" : "Selecionar arquivo do tema",
|
||||
"SettingsXamlThemeFile" : "Arquivo de tema Xaml"
|
||||
"SettingsXamlThemeFile" : "Arquivo de tema Xaml",
|
||||
"SettingsTabHotkeysResScaleUpHotkey": "Aumentar a resolução:",
|
||||
"SettingsTabHotkeysResScaleDownHotkey": "Diminuir a resolução:"
|
||||
}
|
||||
|
@ -554,5 +554,7 @@
|
||||
"ControllerMotionTitle": "Hareket Kontrol Seçenekleri",
|
||||
"ControllerRumbleTitle": "Titreşim Seçenekleri",
|
||||
"SettingsSelectThemeFileDialogTitle" : "Tema Dosyası Seçin",
|
||||
"SettingsXamlThemeFile" : "Xaml Tema Dosyası"
|
||||
"SettingsXamlThemeFile" : "Xaml Tema Dosyası",
|
||||
"SettingsTabHotkeysResScaleUpHotkey": "Çözünürlüğü artırın:",
|
||||
"SettingsTabHotkeysResScaleDownHotkey": "Çözünürlüğü azaltın:"
|
||||
}
|
||||
|
@ -568,5 +568,7 @@
|
||||
"UpdateWindowTitle": "管理游戏更新",
|
||||
"CheatWindowHeading": "适用于 {0} [{1}] 的金手指",
|
||||
"DlcWindowHeading": "适用于 {0} [{1}] 的 DLC",
|
||||
"GameUpdateWindowHeading": "适用于 {0} [{1}] 的更新"
|
||||
"GameUpdateWindowHeading": "适用于 {0} [{1}] 的更新",
|
||||
"SettingsTabHotkeysResScaleUpHotkey": "分辨率提高",
|
||||
"SettingsTabHotkeysResScaleDownHotkey": "降低分辨率"
|
||||
}
|
||||
|
572
Ryujinx.Ava/Assets/Locales/zh_TW.json
Normal file
572
Ryujinx.Ava/Assets/Locales/zh_TW.json
Normal file
@ -0,0 +1,572 @@
|
||||
{
|
||||
"MenuBarFileOpenApplet": "打開小程式",
|
||||
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "打開獨立的 Mii 小程式",
|
||||
"SettingsTabInputDirectMouseAccess": "直通滑鼠操作",
|
||||
"SettingsTabSystemMemoryManagerMode": "記憶體管理模式:",
|
||||
"SettingsTabSystemMemoryManagerModeSoftware": "軟體",
|
||||
"SettingsTabSystemMemoryManagerModeHost": "Host (快速)",
|
||||
"SettingsTabSystemMemoryManagerModeHostUnchecked": "Host 略過檢查 (最快,但較不安全)",
|
||||
"MenuBarFile": "_檔案",
|
||||
"MenuBarFileOpenFromFile": "_載入檔案",
|
||||
"MenuBarFileOpenUnpacked": "載入_解包後的遊戲",
|
||||
"MenuBarFileOpenEmuFolder": "開啟 Ryujinx 資料夾",
|
||||
"MenuBarFileOpenLogsFolder": "開啟日誌資料夾",
|
||||
"MenuBarFileExit": "_退出",
|
||||
"MenuBarOptions": "選項",
|
||||
"MenuBarOptionsToggleFullscreen": "切換全螢幕模式",
|
||||
"MenuBarOptionsStartGamesInFullscreen": "使用全螢幕模式啟動遊戲",
|
||||
"MenuBarOptionsStopEmulation": "停止模擬",
|
||||
"MenuBarOptionsSettings": "_設定",
|
||||
"MenuBarOptionsManageUserProfiles": "_管理使用者帳號",
|
||||
"MenuBarActions": "_動作",
|
||||
"MenuBarOptionsSimulateWakeUpMessage": "模擬喚醒訊息",
|
||||
"MenuBarActionsScanAmiibo": "掃描 Amiibo",
|
||||
"MenuBarTools": "_工具",
|
||||
"MenuBarToolsInstallFirmware": "安裝韌體",
|
||||
"MenuBarFileToolsInstallFirmwareFromFile": "從 XCI 或 ZIP 安裝韌體",
|
||||
"MenuBarFileToolsInstallFirmwareFromDirectory": "從資料夾安裝韌體",
|
||||
"MenuBarHelp": "幫助",
|
||||
"MenuBarHelpCheckForUpdates": "檢查更新",
|
||||
"MenuBarHelpAbout": "關於",
|
||||
"MenuSearch": "搜尋...",
|
||||
"GameListHeaderFavorite": "收藏",
|
||||
"GameListHeaderIcon": "圖示",
|
||||
"GameListHeaderApplication": "名稱",
|
||||
"GameListHeaderDeveloper": "開發商",
|
||||
"GameListHeaderVersion": "版本",
|
||||
"GameListHeaderTimePlayed": "遊玩時間",
|
||||
"GameListHeaderLastPlayed": "上次遊玩",
|
||||
"GameListHeaderFileExtension": "副檔名",
|
||||
"GameListHeaderFileSize": "大小",
|
||||
"GameListHeaderPath": "路徑",
|
||||
"GameListContextMenuOpenUserSaveDirectory": "開啟使用者存檔資料夾",
|
||||
"GameListContextMenuOpenUserSaveDirectoryToolTip": "開啟儲存遊戲存檔的資料夾",
|
||||
"GameListContextMenuOpenUserDeviceDirectory": "開啟系統資料夾",
|
||||
"GameListContextMenuOpenUserDeviceDirectoryToolTip": "開啟包含遊戲系統設定的資料夾",
|
||||
"GameListContextMenuOpenUserBcatDirectory": "開啟 BCAT 資料夾",
|
||||
"GameListContextMenuOpenUserBcatDirectoryToolTip": "開啟包含遊戲 BCAT 資料的資料夾",
|
||||
"GameListContextMenuManageTitleUpdates": "管理遊戲更新",
|
||||
"GameListContextMenuManageTitleUpdatesToolTip": "開啟更新管理視窗",
|
||||
"GameListContextMenuManageDlc": "管理 DLC",
|
||||
"GameListContextMenuManageDlcToolTip": "開啟 DLC 管理視窗",
|
||||
"GameListContextMenuOpenModsDirectory": "開啟模組資料夾",
|
||||
"GameListContextMenuOpenModsDirectoryToolTip": "開啟存放遊戲模組的資料夾",
|
||||
"GameListContextMenuCacheManagement": "快取管理",
|
||||
"GameListContextMenuCacheManagementPurgePptc": "清除 PPTC 快取",
|
||||
"GameListContextMenuCacheManagementPurgePptcToolTip": "刪除遊戲的 PPTC 快取",
|
||||
"GameListContextMenuCacheManagementPurgeShaderCache": "清除渲染器快取",
|
||||
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "刪除遊戲的渲染器快取",
|
||||
"GameListContextMenuCacheManagementOpenPptcDirectory": "開啟 PPTC 資料夾",
|
||||
"GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "開啟包含遊戲 PPTC 快取的資料夾",
|
||||
"GameListContextMenuCacheManagementOpenShaderCacheDirectory": "開啟渲染器快取資料夾",
|
||||
"GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "開啟包含應用程式渲染器快取的資料夾",
|
||||
"GameListContextMenuExtractData": "提取資料",
|
||||
"GameListContextMenuExtractDataExeFS": "ExeFS",
|
||||
"GameListContextMenuExtractDataExeFSToolTip": "從遊戲的目前狀態中提取 ExeFS 分區(包含更新)",
|
||||
"GameListContextMenuExtractDataRomFS": "RomFS",
|
||||
"GameListContextMenuExtractDataRomFSToolTip": "從遊戲的目前狀態中提取 RomFS 分區(包含更新)",
|
||||
"GameListContextMenuExtractDataLogo": "圖示",
|
||||
"GameListContextMenuExtractDataLogoToolTip": "從遊戲的目前狀態中提取圖示(包含更新)",
|
||||
"StatusBarGamesLoaded": "{0}/{1} 遊戲載入完成",
|
||||
"StatusBarSystemVersion": "系統版本: {0}",
|
||||
"Settings": "設定",
|
||||
"SettingsTabGeneral": "使用者介面",
|
||||
"SettingsTabGeneralGeneral": "一般",
|
||||
"SettingsTabGeneralEnableDiscordRichPresence": "啟用 Discord 動態狀態展示",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "自動檢查更新",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "顯示 \"確認離開\" 對話框",
|
||||
"SettingsTabGeneralHideCursorOnIdle": "自動隱藏滑鼠",
|
||||
"SettingsTabGeneralGameDirectories": "遊戲資料夾",
|
||||
"SettingsTabGeneralAdd": "新增",
|
||||
"SettingsTabGeneralRemove": "刪除",
|
||||
"SettingsTabSystem": "系統",
|
||||
"SettingsTabSystemCore": "核心",
|
||||
"SettingsTabSystemSystemRegion": "系統區域:",
|
||||
"SettingsTabSystemSystemRegionJapan": "日本",
|
||||
"SettingsTabSystemSystemRegionUSA": "美國",
|
||||
"SettingsTabSystemSystemRegionEurope": "歐洲",
|
||||
"SettingsTabSystemSystemRegionAustralia": "澳洲",
|
||||
"SettingsTabSystemSystemRegionChina": "中國",
|
||||
"SettingsTabSystemSystemRegionKorea": "韓國",
|
||||
"SettingsTabSystemSystemRegionTaiwan": "台灣",
|
||||
"SettingsTabSystemSystemLanguage": "系統語言:",
|
||||
"SettingsTabSystemSystemLanguageJapanese": "日語",
|
||||
"SettingsTabSystemSystemLanguageAmericanEnglish": "美式英語",
|
||||
"SettingsTabSystemSystemLanguageFrench": "法語",
|
||||
"SettingsTabSystemSystemLanguageGerman": "德語",
|
||||
"SettingsTabSystemSystemLanguageItalian": "義大利語",
|
||||
"SettingsTabSystemSystemLanguageSpanish": "西班牙語",
|
||||
"SettingsTabSystemSystemLanguageChinese": "中文 (中國)",
|
||||
"SettingsTabSystemSystemLanguageKorean": "韓語",
|
||||
"SettingsTabSystemSystemLanguageDutch": "荷蘭語",
|
||||
"SettingsTabSystemSystemLanguagePortuguese": "葡萄牙語",
|
||||
"SettingsTabSystemSystemLanguageRussian": "俄語",
|
||||
"SettingsTabSystemSystemLanguageTaiwanese": "中文 (台灣)",
|
||||
"SettingsTabSystemSystemLanguageBritishEnglish": "英式英語",
|
||||
"SettingsTabSystemSystemLanguageCanadianFrench": "加拿大法語",
|
||||
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "拉美西班牙語",
|
||||
"SettingsTabSystemSystemLanguageSimplifiedChinese": "簡體中文 (推薦)",
|
||||
"SettingsTabSystemSystemLanguageTraditionalChinese": "繁體中文 (推薦)",
|
||||
"SettingsTabSystemSystemTimeZone": "系統時區:",
|
||||
"SettingsTabSystemSystemTime": "系統時鐘:",
|
||||
"SettingsTabSystemEnableVsync": "開啟 VSync",
|
||||
"SettingsTabSystemEnablePptc": "開啟 PPTC 快取",
|
||||
"SettingsTabSystemEnableFsIntegrityChecks": "開啟檔案系統完整性檢查",
|
||||
"SettingsTabSystemAudioBackend": "音訊後端:",
|
||||
"SettingsTabSystemAudioBackendDummy": "無",
|
||||
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
|
||||
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
|
||||
"SettingsTabSystemAudioBackendSDL2": "SDL2",
|
||||
"SettingsTabSystemHacks": "修正",
|
||||
"SettingsTabSystemHacksNote": " - 會引起模擬器不穩定",
|
||||
"SettingsTabSystemExpandDramSize": "將模擬記憶體大小擴充至 6GB",
|
||||
"SettingsTabSystemIgnoreMissingServices": "忽略缺少的服務",
|
||||
"SettingsTabGraphics": "圖形",
|
||||
"SettingsTabGraphicsEnhancements": "增強",
|
||||
"SettingsTabGraphicsEnableShaderCache": "啟用渲染器快取",
|
||||
"SettingsTabGraphicsAnisotropicFiltering": "各向異性過濾:",
|
||||
"SettingsTabGraphicsAnisotropicFilteringAuto": "自動",
|
||||
"SettingsTabGraphicsAnisotropicFiltering2x": "2x",
|
||||
"SettingsTabGraphicsAnisotropicFiltering4x": "4x",
|
||||
"SettingsTabGraphicsAnisotropicFiltering8x": "8x",
|
||||
"SettingsTabGraphicsAnisotropicFiltering16x": "16x",
|
||||
"SettingsTabGraphicsResolutionScale": "解析度縮放:",
|
||||
"SettingsTabGraphicsResolutionScaleCustom": "自訂 (不推薦)",
|
||||
"SettingsTabGraphicsResolutionScaleNative": "原生 (720p/1080p)",
|
||||
"SettingsTabGraphicsResolutionScale2x": "2x (1440p/2160p)",
|
||||
"SettingsTabGraphicsResolutionScale3x": "3x (2160p/3240p)",
|
||||
"SettingsTabGraphicsResolutionScale4x": "4x (2880p/4320p)",
|
||||
"SettingsTabGraphicsAspectRatio": "寬高比:",
|
||||
"SettingsTabGraphicsAspectRatio4x3": "4:3",
|
||||
"SettingsTabGraphicsAspectRatio16x9": "16:9",
|
||||
"SettingsTabGraphicsAspectRatio16x10": "16:10",
|
||||
"SettingsTabGraphicsAspectRatio21x9": "21:9",
|
||||
"SettingsTabGraphicsAspectRatio32x9": "32:9",
|
||||
"SettingsTabGraphicsAspectRatioStretch": "拉伸至螢幕大小",
|
||||
"SettingsTabGraphicsDeveloperOptions": "開發者選項",
|
||||
"SettingsTabGraphicsShaderDumpPath": "圖形渲染器轉儲路徑:",
|
||||
"SettingsTabLogging": "日誌",
|
||||
"SettingsTabLoggingLogging": "日誌",
|
||||
"SettingsTabLoggingEnableLoggingToFile": "儲存日誌為檔案",
|
||||
"SettingsTabLoggingEnableStubLogs": "記錄 Stub",
|
||||
"SettingsTabLoggingEnableInfoLogs": "記錄資訊",
|
||||
"SettingsTabLoggingEnableWarningLogs": "記錄警告",
|
||||
"SettingsTabLoggingEnableErrorLogs": "記錄錯誤",
|
||||
"SettingsTabLoggingEnableTraceLogs": "記錄 Trace",
|
||||
"SettingsTabLoggingEnableGuestLogs": "記錄 Guest",
|
||||
"SettingsTabLoggingEnableFsAccessLogs": "記錄檔案存取",
|
||||
"SettingsTabLoggingFsGlobalAccessLogMode": "記錄全域檔案存取模式:",
|
||||
"SettingsTabLoggingDeveloperOptions": "開發者選項 (警告: 會降低效能)",
|
||||
"SettingsTabLoggingOpenglLogLevel": "OpenGL 日誌級別:",
|
||||
"SettingsTabLoggingOpenglLogLevelNone": "無",
|
||||
"SettingsTabLoggingOpenglLogLevelError": "錯誤",
|
||||
"SettingsTabLoggingOpenglLogLevelPerformance": "減速",
|
||||
"SettingsTabLoggingOpenglLogLevelAll": "全部",
|
||||
"SettingsTabLoggingEnableDebugLogs": "啟用除錯日誌",
|
||||
"SettingsTabInput": "輸入",
|
||||
"SettingsTabInputEnableDockedMode": "Docked 模式",
|
||||
"SettingsTabInputDirectKeyboardAccess": "直通鍵盤控制",
|
||||
"SettingsButtonSave": "儲存",
|
||||
"SettingsButtonClose": "關閉",
|
||||
"SettingsButtonApply": "套用",
|
||||
"ControllerSettingsPlayer": "玩家",
|
||||
"ControllerSettingsPlayer1": "玩家 1",
|
||||
"ControllerSettingsPlayer2": "玩家 2",
|
||||
"ControllerSettingsPlayer3": "玩家 3",
|
||||
"ControllerSettingsPlayer4": "玩家 4",
|
||||
"ControllerSettingsPlayer5": "玩家 5",
|
||||
"ControllerSettingsPlayer6": "玩家 6",
|
||||
"ControllerSettingsPlayer7": "玩家 7",
|
||||
"ControllerSettingsPlayer8": "玩家 8",
|
||||
"ControllerSettingsHandheld": "掌機模式",
|
||||
"ControllerSettingsInputDevice": "輸入設備",
|
||||
"ControllerSettingsRefresh": "更新",
|
||||
"ControllerSettingsDeviceDisabled": "關閉",
|
||||
"ControllerSettingsControllerType": "手把類型",
|
||||
"ControllerSettingsControllerTypeHandheld": "掌機",
|
||||
"ControllerSettingsControllerTypeProController": "Pro 手把",
|
||||
"ControllerSettingsControllerTypeJoyConPair": "JoyCon",
|
||||
"ControllerSettingsControllerTypeJoyConLeft": "左 JoyCon",
|
||||
"ControllerSettingsControllerTypeJoyConRight": "右 JoyCon",
|
||||
"ControllerSettingsProfile": "預設",
|
||||
"ControllerSettingsProfileDefault": "預設",
|
||||
"ControllerSettingsLoad": "載入",
|
||||
"ControllerSettingsAdd": "建立",
|
||||
"ControllerSettingsRemove": "刪除",
|
||||
"ControllerSettingsButtons": "按鈕",
|
||||
"ControllerSettingsButtonA": "A",
|
||||
"ControllerSettingsButtonB": "B",
|
||||
"ControllerSettingsButtonX": "X",
|
||||
"ControllerSettingsButtonY": "Y",
|
||||
"ControllerSettingsButtonPlus": "+",
|
||||
"ControllerSettingsButtonMinus": "-",
|
||||
"ControllerSettingsDPad": "方向鍵",
|
||||
"ControllerSettingsDPadUp": "上",
|
||||
"ControllerSettingsDPadDown": "下",
|
||||
"ControllerSettingsDPadLeft": "左",
|
||||
"ControllerSettingsDPadRight": "右",
|
||||
"ControllerSettingsLStick": "左搖桿",
|
||||
"ControllerSettingsLStickButton": "按下",
|
||||
"ControllerSettingsLStickUp": "上",
|
||||
"ControllerSettingsLStickDown": "下",
|
||||
"ControllerSettingsLStickLeft": "左",
|
||||
"ControllerSettingsLStickRight": "右",
|
||||
"ControllerSettingsLStickStick": "桿",
|
||||
"ControllerSettingsLStickInvertXAxis": "反轉 X 方向",
|
||||
"ControllerSettingsLStickInvertYAxis": "反轉 Y 方向",
|
||||
"ControllerSettingsLStickDeadzone": "死區:",
|
||||
"ControllerSettingsRStick": "右搖桿",
|
||||
"ControllerSettingsRStickButton": "按下",
|
||||
"ControllerSettingsRStickUp": "上",
|
||||
"ControllerSettingsRStickDown": "下",
|
||||
"ControllerSettingsRStickLeft": "左",
|
||||
"ControllerSettingsRStickRight": "右",
|
||||
"ControllerSettingsRStickStick": "桿",
|
||||
"ControllerSettingsRStickInvertXAxis": "反轉 X 方向",
|
||||
"ControllerSettingsRStickInvertYAxis": "反轉 Y 方向",
|
||||
"ControllerSettingsRStickDeadzone": "死區:",
|
||||
"ControllerSettingsTriggersLeft": "左 Triggers",
|
||||
"ControllerSettingsTriggersRight": "右 Triggers",
|
||||
"ControllerSettingsTriggersButtonsLeft": "左 Triggers 鍵",
|
||||
"ControllerSettingsTriggersButtonsRight": "右 Triggers 鍵",
|
||||
"ControllerSettingsTriggers": "Triggers",
|
||||
"ControllerSettingsTriggerL": "L",
|
||||
"ControllerSettingsTriggerR": "R",
|
||||
"ControllerSettingsTriggerZL": "ZL",
|
||||
"ControllerSettingsTriggerZR": "ZR",
|
||||
"ControllerSettingsLeftSL": "SL",
|
||||
"ControllerSettingsLeftSR": "SR",
|
||||
"ControllerSettingsRightSL": "SL",
|
||||
"ControllerSettingsRightSR": "SR",
|
||||
"ControllerSettingsExtraButtonsLeft": "左按鍵",
|
||||
"ControllerSettingsExtraButtonsRight": "右按鍵",
|
||||
"ControllerSettingsMisc": "其他",
|
||||
"ControllerSettingsTriggerThreshold": "Triggers 閾值:",
|
||||
"ControllerSettingsMotion": "體感",
|
||||
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "使用 CemuHook 體感協議",
|
||||
"ControllerSettingsMotionControllerSlot": "手把:",
|
||||
"ControllerSettingsMotionMirrorInput": "鏡像操作",
|
||||
"ControllerSettingsMotionRightJoyConSlot": "右 JoyCon:",
|
||||
"ControllerSettingsMotionServerHost": "伺服器 Host:",
|
||||
"ControllerSettingsMotionGyroSensitivity": "陀螺儀敏感度:",
|
||||
"ControllerSettingsMotionGyroDeadzone": "陀螺儀死區:",
|
||||
"ControllerSettingsSave": "儲存",
|
||||
"ControllerSettingsClose": "關閉",
|
||||
"UserProfilesSelectedUserProfile": "選擇使用者帳號:",
|
||||
"UserProfilesSaveProfileName": "儲存帳號名稱",
|
||||
"UserProfilesChangeProfileImage": "更換頭像",
|
||||
"UserProfilesAvailableUserProfiles": "現有的帳號:",
|
||||
"UserProfilesAddNewProfile": "建立帳號",
|
||||
"UserProfilesDeleteSelectedProfile": "刪除選擇的帳號",
|
||||
"UserProfilesClose": "關閉",
|
||||
"ProfileImageSelectionTitle": "頭像選擇",
|
||||
"ProfileImageSelectionHeader": "選擇合適的頭像圖片",
|
||||
"ProfileImageSelectionNote": "您可以導入自訂頭像,或從系統中選擇頭像",
|
||||
"ProfileImageSelectionImportImage": "導入圖片檔案",
|
||||
"ProfileImageSelectionSelectAvatar": "選擇系統頭像",
|
||||
"InputDialogTitle": "輸入對話框",
|
||||
"InputDialogOk": "完成",
|
||||
"InputDialogCancel": "取消",
|
||||
"InputDialogAddNewProfileTitle": "選擇使用者名稱",
|
||||
"InputDialogAddNewProfileHeader": "請輸入帳號名稱",
|
||||
"InputDialogAddNewProfileSubtext": "(最大長度: {0})",
|
||||
"AvatarChoose": "選擇",
|
||||
"AvatarSetBackgroundColor": "設定背景顏色",
|
||||
"AvatarClose": "關閉",
|
||||
"ControllerSettingsLoadProfileToolTip": "載入預設",
|
||||
"ControllerSettingsAddProfileToolTip": "新增預設",
|
||||
"ControllerSettingsRemoveProfileToolTip": "刪除預設",
|
||||
"ControllerSettingsSaveProfileToolTip": "儲存預設",
|
||||
"MenuBarFileToolsTakeScreenshot": "儲存截圖",
|
||||
"MenuBarFileToolsHideUi": "隱藏 UI",
|
||||
"GameListContextMenuToggleFavorite": "標記為收藏",
|
||||
"GameListContextMenuToggleFavoriteToolTip": "啟用或取消收藏標記",
|
||||
"SettingsTabGeneralTheme": "主題",
|
||||
"SettingsTabGeneralThemeCustomTheme": "自定主題路徑",
|
||||
"SettingsTabGeneralThemeBaseStyle": "主題樣式",
|
||||
"SettingsTabGeneralThemeBaseStyleDark": "深色模式",
|
||||
"SettingsTabGeneralThemeBaseStyleLight": "淺色模式",
|
||||
"SettingsTabGeneralThemeEnableCustomTheme": "使用自訂主題介面",
|
||||
"ButtonBrowse": "瀏覽",
|
||||
"ControllerSettingsConfigureGeneral": "配置",
|
||||
"ControllerSettingsRumble": "震動",
|
||||
"ControllerSettingsRumbleStrongMultiplier": "強震動調節",
|
||||
"ControllerSettingsRumbleWeakMultiplier": "弱震動調節",
|
||||
"DialogMessageSaveNotAvailableMessage": "沒有{0} [{1:x16}]的遊戲存檔",
|
||||
"DialogMessageSaveNotAvailableCreateSaveMessage": "是否建立該遊戲的存檔資料夾?",
|
||||
"DialogConfirmationTitle": "Ryujinx - 設定",
|
||||
"DialogUpdaterTitle": "Ryujinx - 更新",
|
||||
"DialogErrorTitle": "Ryujinx - 錯誤",
|
||||
"DialogWarningTitle": "Ryujinx - 警告",
|
||||
"DialogExitTitle": "Ryujinx - 關閉",
|
||||
"DialogErrorMessage": "Ryujinx 遇到了錯誤",
|
||||
"DialogExitMessage": "是否關閉 Ryujinx?",
|
||||
"DialogExitSubMessage": "所有未儲存的進度會遺失!",
|
||||
"DialogMessageCreateSaveErrorMessage": "建立特定的存檔時出錯: {0}",
|
||||
"DialogMessageFindSaveErrorMessage": "查找特定的存檔時出錯: {0}",
|
||||
"FolderDialogExtractTitle": "選擇要解壓到的資料夾",
|
||||
"DialogNcaExtractionMessage": "提取{1}的{0}分區...",
|
||||
"DialogNcaExtractionTitle": "Ryujinx - NCA分區提取",
|
||||
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "提取失敗。所選檔案中不含主NCA檔案",
|
||||
"DialogNcaExtractionCheckLogErrorMessage": "提取失敗。請查看日誌檔案取得詳情。",
|
||||
"DialogNcaExtractionSuccessMessage": "提取成功。",
|
||||
"DialogUpdaterConvertFailedMessage": "無法轉換目前 Ryujinx 版本。",
|
||||
"DialogUpdaterCancelUpdateMessage": "更新取消!",
|
||||
"DialogUpdaterAlreadyOnLatestVersionMessage": "您使用的 Ryujinx 是最新版本。",
|
||||
"DialogUpdaterFailedToGetVersionMessage": "嘗試從 Github 取得版本訊息時無效。可能是因為 GitHub Actions 正在編譯新版本。請過幾分鐘重試。",
|
||||
"DialogUpdaterConvertFailedGithubMessage": "無法轉換從 Github 接收到的 Ryujinx 版本。",
|
||||
"DialogUpdaterDownloadingMessage": "下載新版本中...",
|
||||
"DialogUpdaterExtractionMessage": "正在提取更新...",
|
||||
"DialogUpdaterRenamingMessage": "正在刪除舊檔案...",
|
||||
"DialogUpdaterAddingFilesMessage": "安裝更新中...",
|
||||
"DialogUpdaterCompleteMessage": "更新成功!",
|
||||
"DialogUpdaterRestartMessage": "立即重啟 Ryujinx 完成更新?",
|
||||
"DialogUpdaterArchNotSupportedMessage": "您執行的系統架構不受支援!",
|
||||
"DialogUpdaterArchNotSupportedSubMessage": "(僅支援 x64 系統)",
|
||||
"DialogUpdaterNoInternetMessage": "沒有連接到網路",
|
||||
"DialogUpdaterNoInternetSubMessage": "請確保網路連接正常。",
|
||||
"DialogUpdaterDirtyBuildMessage": "不能更新非官方版本的 Ryujinx!",
|
||||
"DialogUpdaterDirtyBuildSubMessage": "如果希望使用受支援的版本,請您在 https://ryujinx.org/ 下載。",
|
||||
"DialogRestartRequiredMessage": "需要重啟模擬器",
|
||||
"DialogThemeRestartMessage": "主題設定已儲存。需要重新啟動才能生效。",
|
||||
"DialogThemeRestartSubMessage": "您是否要重啟?",
|
||||
"DialogFirmwareInstallEmbeddedMessage": "要安裝遊戲內建的韌體嗎?(韌體 {0})",
|
||||
"DialogFirmwareInstallEmbeddedSuccessMessage": "未找到已安裝的韌體,但 Ryujinx 可以從現有的遊戲安裝韌體{0}.\\n模擬器現在可以執行。",
|
||||
"DialogFirmwareNoFirmwareInstalledMessage": "未安裝韌體",
|
||||
"DialogFirmwareInstalledMessage": "已安裝韌體{0}",
|
||||
"DialogOpenSettingsWindowLabel": "打開設定視窗",
|
||||
"DialogControllerAppletTitle": "控制器小視窗",
|
||||
"DialogMessageDialogErrorExceptionMessage": "顯示訊息對話框時出錯: {0}",
|
||||
"DialogSoftwareKeyboardErrorExceptionMessage": "顯示軟體鍵盤時出錯: {0}",
|
||||
"DialogErrorAppletErrorExceptionMessage": "顯示錯誤對話框時出錯: {0}",
|
||||
"DialogUserErrorDialogMessage": "{0}: {1}",
|
||||
"DialogUserErrorDialogInfoMessage": "\n有關修復此錯誤的更多訊息,可以遵循我們的設定指南。",
|
||||
"DialogUserErrorDialogTitle": "Ryujinx 錯誤 ({0})",
|
||||
"DialogAmiiboApiTitle": "Amiibo API",
|
||||
"DialogAmiiboApiFailFetchMessage": "從 API 取得訊息時出錯。",
|
||||
"DialogAmiiboApiConnectErrorMessage": "無法連接到 Amiibo API 伺服器。伺服器可能已關閉,或者您沒有網路連接。",
|
||||
"DialogProfileInvalidProfileErrorMessage": "預設{0} 與目前輸入配置系統不相容。",
|
||||
"DialogProfileDefaultProfileOverwriteErrorMessage": "默認預設無法被覆蓋",
|
||||
"DialogProfileDeleteProfileTitle": "刪除預設",
|
||||
"DialogProfileDeleteProfileMessage": "刪除後不可恢復,確定嗎?",
|
||||
"DialogWarning": "警告",
|
||||
"DialogPPTCDeletionMessage": "您即將刪除:\n\n{0}的 PPTC 快取\n\n確定嗎?",
|
||||
"DialogPPTCDeletionErrorMessage": "清除位於{0}的 PPTC 快取時出錯: {1}",
|
||||
"DialogShaderDeletionMessage": "您即將刪除:\n\n{0}的渲染器快取\n\n確定嗎?",
|
||||
"DialogShaderDeletionErrorMessage": "清除位於{0}的渲染器快取時出錯: {1}",
|
||||
"DialogRyujinxErrorMessage": "Ryujinx 遇到錯誤",
|
||||
"DialogInvalidTitleIdErrorMessage": "UI 錯誤:所選遊戲沒有有效的標題ID",
|
||||
"DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "路徑{0}找不到有效的系統韌體。",
|
||||
"DialogFirmwareInstallerFirmwareInstallTitle": "安裝韌體{0}",
|
||||
"DialogFirmwareInstallerFirmwareInstallMessage": "將安裝{0}版本的系統。",
|
||||
"DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\n這將替換目前系統版本{0}。",
|
||||
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\n確認進行?",
|
||||
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "安裝韌體中...",
|
||||
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "成功安裝系統版本{0}。",
|
||||
"DialogUserProfileDeletionWarningMessage": "刪除後將沒有可選擇的使用者帳號",
|
||||
"DialogUserProfileDeletionConfirmMessage": "是否刪除選擇的帳號",
|
||||
"DialogControllerSettingsModifiedConfirmMessage": "目前的輸入預設已更新",
|
||||
"DialogControllerSettingsModifiedConfirmSubMessage": "要儲存嗎?",
|
||||
"DialogDlcLoadNcaErrorMessage": "{0}. 錯誤的檔案: {1}",
|
||||
"DialogDlcNoDlcErrorMessage": "選擇的檔案不包含所選遊戲的 DLC!",
|
||||
"DialogPerformanceCheckLoggingEnabledMessage": "您啟用了跟蹤日誌,僅供開發人員使用。",
|
||||
"DialogPerformanceCheckLoggingEnabledConfirmMessage": "為了獲得最佳效能,建議停用跟蹤日誌記錄。您是否要立即停用?",
|
||||
"DialogPerformanceCheckShaderDumpEnabledMessage": "您啟用了渲染器轉儲,僅供開發人員使用。",
|
||||
"DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "為了獲得最佳效能,建議停用渲染器轉儲。您是否要立即停用?",
|
||||
"DialogLoadAppGameAlreadyLoadedMessage": "目前已載入有遊戲",
|
||||
"DialogLoadAppGameAlreadyLoadedSubMessage": "請停止模擬或關閉程式,再啟動另一個遊戲。",
|
||||
"DialogUpdateAddUpdateErrorMessage": "選擇的檔案不包含所選遊戲的更新!",
|
||||
"DialogSettingsBackendThreadingWarningTitle": "警告 - 後端多執行緒",
|
||||
"DialogSettingsBackendThreadingWarningMessage": "改變此選項後必須重啟 Ryujinx 才能生效。根據您的硬體,您開啟該選項時,可能需要手動停用驅動程式本身的GL多執行緒。",
|
||||
"SettingsTabGraphicsFeaturesOptions": "功能",
|
||||
"SettingsTabGraphicsBackendMultithreading": "後端多執行緒:",
|
||||
"CommonAuto": "自動(推薦)",
|
||||
"CommonOff": "關閉",
|
||||
"CommonOn": "打開",
|
||||
"InputDialogYes": "是",
|
||||
"InputDialogNo": "否",
|
||||
"DialogProfileInvalidProfileNameErrorMessage": "檔案名包含無效字元,請重試。",
|
||||
"MenuBarOptionsPauseEmulation": "暫停",
|
||||
"MenuBarOptionsResumeEmulation": "繼續",
|
||||
"AboutUrlTooltipMessage": "在瀏覽器中打開 Ryujinx 的官網。",
|
||||
"AboutDisclaimerMessage": "Ryujinx 以任何方式與 Nintendo™ 及其合作伙伴都沒有任何關聯。",
|
||||
"AboutAmiiboDisclaimerMessage": "我們的 Amiibo 模擬使用了\nAmiiboAPI (www.amiiboapi.com) ",
|
||||
"AboutPatreonUrlTooltipMessage": "在瀏覽器中打開 Ryujinx 的 Patreon 贊助頁。",
|
||||
"AboutGithubUrlTooltipMessage": "在瀏覽器中打開 Ryujinx 的 GitHub 儲存庫。",
|
||||
"AboutDiscordUrlTooltipMessage": "在瀏覽器中打開 Ryujinx 的 Discord 伺服器邀請連結。",
|
||||
"AboutTwitterUrlTooltipMessage": "在瀏覽器中打開 Ryujinx 的 Twitter 首頁。",
|
||||
"AboutRyujinxAboutTitle": "關於:",
|
||||
"AboutRyujinxAboutContent": "Ryujinx 是一款 Nintendo Switch™ 模擬器。\n您可以在 Patreon 上贊助 Ryujinx。\n關注 Twitter 或 Discord 可以取得模擬器最新動態。\n如果您對開發本軟體感興趣,歡迎來 GitHub 和 Discord 加入我們!",
|
||||
"AboutRyujinxMaintainersTitle": "由以下作者維護:",
|
||||
"AboutRyujinxMaintainersContentTooltipMessage": "在瀏覽器中打開貢獻者的網頁",
|
||||
"AboutRyujinxSupprtersTitle": "感謝 Patreon 的贊助者:",
|
||||
"AmiiboSeriesLabel": "Amiibo 系列",
|
||||
"AmiiboCharacterLabel": "角色",
|
||||
"AmiiboScanButtonLabel": "掃描",
|
||||
"AmiiboOptionsShowAllLabel": "顯示所有 Amiibo",
|
||||
"AmiiboOptionsUsRandomTagLabel": "修正: 使用隨機標記的 Uuid",
|
||||
"DlcManagerTableHeadingEnabledLabel": "啟用",
|
||||
"DlcManagerTableHeadingTitleIdLabel": "遊戲ID",
|
||||
"DlcManagerTableHeadingContainerPathLabel": "資料夾路徑",
|
||||
"DlcManagerTableHeadingFullPathLabel": "完整路徑",
|
||||
"DlcManagerRemoveAllButton": "全部刪除",
|
||||
"MenuBarOptionsChangeLanguage": "變更語言",
|
||||
"CommonSort": "排序",
|
||||
"CommonShowNames": "顯示名稱",
|
||||
"CommonFavorite": "收藏",
|
||||
"OrderAscending": "從小到大",
|
||||
"OrderDescending": "從大到小",
|
||||
"SettingsTabGraphicsFeatures": "額外功能",
|
||||
"ErrorWindowTitle": "錯誤視窗",
|
||||
"ToggleDiscordTooltip": "啟用或關閉 Discord 動態狀態展示",
|
||||
"AddGameDirBoxTooltip": "輸入要添加的遊戲資料夾",
|
||||
"AddGameDirTooltip": "添加遊戲資料夾到列表中",
|
||||
"RemoveGameDirTooltip": "移除選中的資料夾",
|
||||
"CustomThemeCheckTooltip": "啟用或關閉自訂主題",
|
||||
"CustomThemePathTooltip": "自訂主題的資料夾",
|
||||
"CustomThemeBrowseTooltip": "查找自訂主題",
|
||||
"DockModeToggleTooltip": "是否開啟 Switch 的 Docked 模式",
|
||||
"DirectKeyboardTooltip": "是否開啟\"直連鍵盤存取(HID) 支援\"\n(部分遊戲可以使用您的鍵盤輸入文字)",
|
||||
"DirectMouseTooltip": "是否開啟\"直連滑鼠存取(HID) 支援\"\n(部分遊戲可以使用您的滑鼠導航)",
|
||||
"RegionTooltip": "變更系統區域",
|
||||
"LanguageTooltip": "變更系統語言",
|
||||
"TimezoneTooltip": "變更系統時區",
|
||||
"TimeTooltip": "變更系統時鐘",
|
||||
"VSyncToggleTooltip": "關閉後,部分使用動態幀率的遊戲可以超過 60Hz 更新率",
|
||||
"PptcToggleTooltip": "開啟以後減少遊戲啟動時間和卡頓",
|
||||
"FsIntegrityToggleTooltip": "是否檢查遊戲檔案內容的完整性",
|
||||
"AudioBackendTooltip": "默認推薦SDL,但每種音訊後端對各類遊戲相容性不同,遇到音訊問題可以切換後端",
|
||||
"MemoryManagerTooltip": "改變 Switch 記憶體映射到電腦記憶體的方式,會影響CPU效能消耗",
|
||||
"MemoryManagerSoftwareTooltip": "使用軟體記憶體頁管理,最精確但是速度最慢",
|
||||
"MemoryManagerHostTooltip": "直接映射記憶體頁到電腦記憶體,JIT效率高",
|
||||
"MemoryManagerUnsafeTooltip": "直接映射記憶體頁,但是不檢查記憶體溢出,JIT效率最高。\nRyujinx可以存取任何位置的記憶體,因而相對不安全。此模式下只應執行您信任的遊戲或軟體(即官方遊戲)",
|
||||
"DRamTooltip": "擴展模擬的 Switch 記憶體為6GB,某些高畫質材質模組或 4K 模組需要此選項",
|
||||
"IgnoreMissingServicesTooltip": "忽略某些未實現的系統服務,少部分遊戲需要此選項才能啟動",
|
||||
"GraphicsBackendThreadingTooltip": "啟用後端多執行緒",
|
||||
"GalThreadingTooltip": "使用模擬器自帶的多執行緒調度,減少渲染器編譯的卡頓,並提高驅動程式的效能(尤其是缺失多執行緒的AMD)。\nNVIDIA使用者需要重啟模擬器才能停用驅動本身的多執行緒,否則您需手動執行停用獲得最佳效能",
|
||||
"ShaderCacheToggleTooltip": "開啟後快取渲染器到硬碟,減少遊戲卡頓",
|
||||
"ResolutionScaleTooltip": "縮放渲染的解析度",
|
||||
"ResolutionScaleEntryTooltip": "盡量使用如1.5的浮點倍數。非整數的倍率易引起錯誤",
|
||||
"AnisotropyTooltip": "各向異性過濾等級。提高傾斜視角材質的清晰度\n('自動'使用遊戲默認指定的等級)",
|
||||
"AspectRatioTooltip": "模擬器渲染視窗的寬高比",
|
||||
"ShaderDumpPathTooltip": "轉儲圖形渲染器的路徑",
|
||||
"FileLogTooltip": "是否儲存日誌檔案到硬碟",
|
||||
"StubLogTooltip": "記錄 Stub 訊息",
|
||||
"InfoLogTooltip": "記錄資訊訊息",
|
||||
"WarnLogTooltip": "記錄警告訊息",
|
||||
"ErrorLogTooltip": "記錄錯誤訊息",
|
||||
"TraceLogTooltip": "記錄 Trace 訊息",
|
||||
"GuestLogTooltip": "記錄 Guest 訊息",
|
||||
"FileAccessLogTooltip": "記錄檔案存取訊息",
|
||||
"FSAccessLogModeTooltip": "記錄 FS 存取訊息,輸出到控制台。可選的模式是0-3",
|
||||
"DeveloperOptionTooltip": "使用請謹慎",
|
||||
"OpenGlLogLevel": "需要打開適當的日誌等級",
|
||||
"DebugLogTooltip": "記錄Debug訊息",
|
||||
"LoadApplicationFileTooltip": "選擇 Switch 支援的遊戲格式並載入",
|
||||
"LoadApplicationFolderTooltip": "選擇解包後的 Switch 遊戲並載入",
|
||||
"OpenRyujinxFolderTooltip": "打開 Ryujinx 系統資料夾",
|
||||
"OpenRyujinxLogsTooltip": "打開日誌存放的資料夾",
|
||||
"ExitTooltip": "關閉 Ryujinx",
|
||||
"OpenSettingsTooltip": "打開設定視窗",
|
||||
"OpenProfileManagerTooltip": "打開使用者帳號管理器",
|
||||
"StopEmulationTooltip": "停止執行目前遊戲並回到選擇界面",
|
||||
"CheckUpdatesTooltip": "檢查 Ryujinx 新版本",
|
||||
"OpenAboutTooltip": "開啟關於視窗",
|
||||
"GridSize": "網格尺寸",
|
||||
"GridSizeTooltip": "調整網格模式的大小",
|
||||
"SettingsTabSystemSystemLanguageBrazilianPortuguese": "巴西葡萄牙語",
|
||||
"AboutRyujinxContributorsButtonHeader": "查看所有參與者",
|
||||
"SettingsTabSystemAudioVolume": "音量: ",
|
||||
"AudioVolumeTooltip": "調節音量",
|
||||
"SettingsTabSystemEnableInternetAccess": "啟用網路連接",
|
||||
"EnableInternetAccessTooltip": "開啟網路存取。此選項打開後,效果類似於 Switch 連接到網路的狀態。注意即使此選項關閉,應用程式偶爾也有可能連接到網路",
|
||||
"GameListContextMenuManageCheatToolTip": "管理金手指",
|
||||
"GameListContextMenuManageCheat": "管理金手指",
|
||||
"ControllerSettingsStickRange": "範圍",
|
||||
"DialogStopEmulationTitle": "Ryujinx - 停止模擬",
|
||||
"DialogStopEmulationMessage": "是否確定停止模擬?",
|
||||
"SettingsTabCpu": "CPU",
|
||||
"SettingsTabAudio": "音訊",
|
||||
"SettingsTabNetwork": "網路",
|
||||
"SettingsTabNetworkConnection": "網路連接",
|
||||
"SettingsTabCpuCache": "CPU 快取",
|
||||
"SettingsTabCpuMemory": "CPU 記憶體",
|
||||
"DialogUpdaterFlatpakNotSupportedMessage": "請透過 Flathub 更新 Ryujinx。",
|
||||
"UpdaterDisabledWarningTitle": "更新已停用!",
|
||||
"GameListContextMenuOpenSdModsDirectory": "打開 Atmosphere 模組資料夾",
|
||||
"GameListContextMenuOpenSdModsDirectoryToolTip": "打開包含應用程式模組的額外 Atmosphere SD卡資料夾",
|
||||
"ControllerSettingsRotate90": "順時針旋轉 90°",
|
||||
"IconSize": "圖示尺寸",
|
||||
"IconSizeTooltip": "變更遊戲圖示大小",
|
||||
"MenuBarOptionsShowConsole": "顯示控制台",
|
||||
"ShaderCachePurgeError": "清除渲染器快取時出錯: {0}: {1}",
|
||||
"UserErrorNoKeys": "找不到金鑰",
|
||||
"UserErrorNoFirmware": "找不到韌體",
|
||||
"UserErrorFirmwareParsingFailed": "韌體解析錯誤",
|
||||
"UserErrorApplicationNotFound": "找不到應用程式",
|
||||
"UserErrorUnknown": "未知錯誤",
|
||||
"UserErrorUndefined": "未定義錯誤",
|
||||
"UserErrorNoKeysDescription": "Ryujinx 找不到 『prod.keys』 檔案",
|
||||
"UserErrorNoFirmwareDescription": "Ryujinx 找不到任何已安裝的韌體",
|
||||
"UserErrorFirmwareParsingFailedDescription": "Ryujinx 無法解密選擇的韌體。這通常是由於金鑰過舊。",
|
||||
"UserErrorApplicationNotFoundDescription": "Ryujinx 在選中路徑找不到有效的應用程式。",
|
||||
"UserErrorUnknownDescription": "發生未知錯誤!",
|
||||
"UserErrorUndefinedDescription": "發生了未定義錯誤!此類錯誤不應出現,請聯絡開發人員!",
|
||||
"OpenSetupGuideMessage": "打開設定教學",
|
||||
"NoUpdate": "沒有新版本",
|
||||
"TitleUpdateVersionLabel": "版本 {0} - {1}",
|
||||
"RyujinxInfo": "Ryujinx - 訊息",
|
||||
"RyujinxConfirm": "Ryujinx - 確認",
|
||||
"FileDialogAllTypes": "全部類型",
|
||||
"Never": "從不",
|
||||
"SwkbdMinCharacters": "至少應為 {0} 個字長",
|
||||
"SwkbdMinRangeCharacters": "必須為 {0}-{1} 個字長",
|
||||
"SoftwareKeyboard": "軟體鍵盤",
|
||||
"DialogControllerAppletMessagePlayerRange": "遊戲需要 {0} 個玩家()持有:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}請打開設定界面,配置手把;或者關閉視窗。",
|
||||
"DialogControllerAppletMessage": "遊戲需要剛好 {0} 個玩家()持有 with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}請打開設定界面,配置手把;或者關閉視窗。",
|
||||
"DialogControllerAppletDockModeSet": "現在處於主機模式,無法使用掌機操作方式\n\n",
|
||||
"UpdaterRenaming": "正在刪除舊檔案...",
|
||||
"UpdaterRenameFailed": "更新過程中無法重命名檔案: {0}",
|
||||
"UpdaterAddingFiles": "安裝更新中...",
|
||||
"UpdaterExtracting": "正在提取更新...",
|
||||
"UpdaterDownloading": "下載新版本中...",
|
||||
"Game": "遊戲",
|
||||
"Docked": "主機模式",
|
||||
"Handheld": "掌機模式",
|
||||
"ConnectionError": "連接錯誤。",
|
||||
"AboutPageDeveloperListMore": "{0} 等開發者...",
|
||||
"ApiError": "API 錯誤",
|
||||
"LoadingHeading": "正在啟動 {0}",
|
||||
"CompilingPPTC": "編譯 PPTC 快取中",
|
||||
"CompilingShaders": "編譯渲染器中",
|
||||
"AllKeyboards": "所有鍵盤",
|
||||
"OpenFileDialogTitle": "選擇支援的檔案格式",
|
||||
"OpenFolderDialogTitle": "選擇一個包含解包遊戲的資料夾",
|
||||
"AllSupportedFormats": "全部支援的格式",
|
||||
"RyujinxUpdater": "Ryujinx 更新程式",
|
||||
"SettingsTabHotkeys": "快捷鍵",
|
||||
"SettingsTabHotkeysHotkeys": "鍵盤快捷鍵",
|
||||
"SettingsTabHotkeysToggleVsyncHotkey": "切換垂直同步",
|
||||
"SettingsTabHotkeysScreenshotHotkey": "截圖",
|
||||
"SettingsTabHotkeysShowUiHotkey": "隱藏 UI",
|
||||
"SettingsTabHotkeysPauseHotkey": "暫停",
|
||||
"SettingsTabHotkeysToggleMuteHotkey": "靜音",
|
||||
"ControllerMotionTitle": "體感操作設定",
|
||||
"ControllerRumbleTitle": "震動設定",
|
||||
"SettingsSelectThemeFileDialogTitle": "選擇主題檔案",
|
||||
"SettingsXamlThemeFile": "Xaml 主題檔案",
|
||||
"AvatarWindowTitle": "管理帳號 - 頭像",
|
||||
"Amiibo": "Amiibo",
|
||||
"Unknown": "未知",
|
||||
"Usage": "用途",
|
||||
"Writable": "可寫入",
|
||||
"SelectDlcDialogTitle": "選擇 DLC 檔案",
|
||||
"SelectUpdateDialogTitle": "選擇更新檔",
|
||||
"UserProfileWindowTitle": "管理使用者設定檔",
|
||||
"CheatWindowTitle": "管理遊戲金手指",
|
||||
"DlcWindowTitle": "管理遊戲 DLC",
|
||||
"UpdateWindowTitle": "管理遊戲更新",
|
||||
"CheatWindowHeading": "金手指可用於 {0} [{1}]",
|
||||
"DlcWindowHeading": "DLC 可用於 {0} [{1}]",
|
||||
"GameUpdateWindowHeading": "更新可用於 {0} [{1}]"
|
||||
}
|
@ -81,7 +81,6 @@ namespace Ryujinx.Ava.Common
|
||||
Dispatcher.UIThread.Post(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(
|
||||
_owner,
|
||||
string.Format(LocaleManager.Instance["DialogMessageCreateSaveErrorMessage"], result.ToStringWithName()));
|
||||
});
|
||||
|
||||
@ -101,8 +100,7 @@ namespace Ryujinx.Ava.Common
|
||||
|
||||
Dispatcher.UIThread.Post(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner,
|
||||
string.Format(LocaleManager.Instance["DialogMessageFindSaveErrorMessage"], result.ToStringWithName()));
|
||||
await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogMessageFindSaveErrorMessage"], result.ToStringWithName()));
|
||||
});
|
||||
|
||||
return false;
|
||||
@ -161,7 +159,6 @@ namespace Ryujinx.Ava.Common
|
||||
Dispatcher.UIThread.Post(async () =>
|
||||
{
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
|
||||
_owner,
|
||||
string.Format(LocaleManager.Instance["DialogNcaExtractionMessage"], ncaSectionType, Path.GetFileName(titleFilePath)),
|
||||
"",
|
||||
"",
|
||||
@ -232,7 +229,7 @@ namespace Ryujinx.Ava.Common
|
||||
"Extraction failure. The main NCA was not present in the selected file");
|
||||
Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner, LocaleManager.Instance["DialogNcaExtractionMainNcaNotFoundErrorMessage"]);
|
||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogNcaExtractionMainNcaNotFoundErrorMessage"]);
|
||||
});
|
||||
return;
|
||||
}
|
||||
@ -273,7 +270,7 @@ namespace Ryujinx.Ava.Common
|
||||
$"LibHac returned error code: {resultCode.Value.ErrorCode}");
|
||||
Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner, LocaleManager.Instance["DialogNcaExtractionCheckLogErrorMessage"]);
|
||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogNcaExtractionCheckLogErrorMessage"]);
|
||||
});
|
||||
}
|
||||
else if (resultCode.Value.IsSuccess())
|
||||
@ -281,7 +278,6 @@ namespace Ryujinx.Ava.Common
|
||||
Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateInfoDialog(
|
||||
_owner,
|
||||
LocaleManager.Instance["DialogNcaExtractionSuccessMessage"],
|
||||
"",
|
||||
LocaleManager.Instance["InputDialogOk"],
|
||||
@ -298,7 +294,7 @@ namespace Ryujinx.Ava.Common
|
||||
{
|
||||
Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner, ex.Message);
|
||||
await ContentDialogHelper.CreateErrorDialog(ex.Message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,8 @@
|
||||
Screenshot,
|
||||
ShowUi,
|
||||
Pause,
|
||||
ToggleMute
|
||||
ToggleMute,
|
||||
ResScaleUp,
|
||||
ResScaleDown
|
||||
}
|
||||
}
|
@ -76,7 +76,7 @@ namespace Ryujinx.Modules
|
||||
Logger.Error?.Print(LogClass.Application, "Failed to convert the current Ryujinx version!");
|
||||
Dispatcher.UIThread.Post(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateWarningDialog(mainWindow, LocaleManager.Instance["DialogUpdaterConvertFailedMessage"], LocaleManager.Instance["DialogUpdaterCancelUpdateMessage"]);
|
||||
await ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["DialogUpdaterConvertFailedMessage"], LocaleManager.Instance["DialogUpdaterCancelUpdateMessage"]);
|
||||
});
|
||||
|
||||
return;
|
||||
@ -111,7 +111,7 @@ namespace Ryujinx.Modules
|
||||
{
|
||||
Dispatcher.UIThread.Post(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateUpdaterInfoDialog(mainWindow, LocaleManager.Instance["DialogUpdaterAlreadyOnLatestVersionMessage"], "");
|
||||
await ContentDialogHelper.CreateUpdaterInfoDialog(LocaleManager.Instance["DialogUpdaterAlreadyOnLatestVersionMessage"], "");
|
||||
});
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ namespace Ryujinx.Modules
|
||||
{
|
||||
Dispatcher.UIThread.Post(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateUpdaterInfoDialog(mainWindow, LocaleManager.Instance["DialogUpdaterAlreadyOnLatestVersionMessage"], "");
|
||||
await ContentDialogHelper.CreateUpdaterInfoDialog(LocaleManager.Instance["DialogUpdaterAlreadyOnLatestVersionMessage"], "");
|
||||
});
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ namespace Ryujinx.Modules
|
||||
Logger.Error?.Print(LogClass.Application, exception.Message);
|
||||
Dispatcher.UIThread.Post(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(mainWindow, LocaleManager.Instance["DialogUpdaterFailedToGetVersionMessage"]);
|
||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogUpdaterFailedToGetVersionMessage"]);
|
||||
});
|
||||
|
||||
return;
|
||||
@ -157,7 +157,7 @@ namespace Ryujinx.Modules
|
||||
Logger.Error?.Print(LogClass.Application, "Failed to convert the received Ryujinx version from Github!");
|
||||
Dispatcher.UIThread.Post(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateWarningDialog(mainWindow, LocaleManager.Instance["DialogUpdaterConvertFailedGithubMessage"], LocaleManager.Instance["DialogUpdaterCancelUpdateMessage"]);
|
||||
await ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["DialogUpdaterConvertFailedGithubMessage"], LocaleManager.Instance["DialogUpdaterCancelUpdateMessage"]);
|
||||
});
|
||||
|
||||
return;
|
||||
@ -169,7 +169,7 @@ namespace Ryujinx.Modules
|
||||
{
|
||||
Dispatcher.UIThread.Post(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateUpdaterInfoDialog(mainWindow, LocaleManager.Instance["DialogUpdaterAlreadyOnLatestVersionMessage"], "");
|
||||
await ContentDialogHelper.CreateUpdaterInfoDialog(LocaleManager.Instance["DialogUpdaterAlreadyOnLatestVersionMessage"], "");
|
||||
});
|
||||
}
|
||||
|
||||
@ -550,7 +550,7 @@ namespace Ryujinx.Modules
|
||||
{
|
||||
if (showWarnings)
|
||||
{
|
||||
ContentDialogHelper.CreateWarningDialog(parent, LocaleManager.Instance["DialogUpdaterArchNotSupportedMessage"],
|
||||
ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["DialogUpdaterArchNotSupportedMessage"],
|
||||
LocaleManager.Instance["DialogUpdaterArchNotSupportedSubMessage"]);
|
||||
}
|
||||
|
||||
@ -561,7 +561,7 @@ namespace Ryujinx.Modules
|
||||
{
|
||||
if (showWarnings)
|
||||
{
|
||||
ContentDialogHelper.CreateWarningDialog(parent, LocaleManager.Instance["DialogUpdaterNoInternetMessage"],
|
||||
ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["DialogUpdaterNoInternetMessage"],
|
||||
LocaleManager.Instance["DialogUpdaterNoInternetSubMessage"]);
|
||||
}
|
||||
|
||||
@ -572,7 +572,7 @@ namespace Ryujinx.Modules
|
||||
{
|
||||
if (showWarnings)
|
||||
{
|
||||
ContentDialogHelper.CreateWarningDialog(parent, LocaleManager.Instance["DialogUpdaterDirtyBuildMessage"],
|
||||
ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["DialogUpdaterDirtyBuildMessage"],
|
||||
LocaleManager.Instance["DialogUpdaterDirtyBuildSubMessage"]);
|
||||
}
|
||||
|
||||
@ -585,13 +585,11 @@ namespace Ryujinx.Modules
|
||||
{
|
||||
if (ReleaseInformations.IsFlatHubBuild())
|
||||
{
|
||||
ContentDialogHelper.CreateWarningDialog(parent,
|
||||
LocaleManager.Instance["UpdaterDisabledWarningTitle"], LocaleManager.Instance["DialogUpdaterFlatpakNotSupportedMessage"]);
|
||||
ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["UpdaterDisabledWarningTitle"], LocaleManager.Instance["DialogUpdaterFlatpakNotSupportedMessage"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ContentDialogHelper.CreateWarningDialog(parent,
|
||||
LocaleManager.Instance["UpdaterDisabledWarningTitle"], LocaleManager.Instance["DialogUpdaterDirtyBuildSubMessage"]);
|
||||
ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["UpdaterDisabledWarningTitle"], LocaleManager.Instance["DialogUpdaterDirtyBuildSubMessage"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
<PackageReference Include="jp2masa.Avalonia.Flexbox" Version="0.2.0" />
|
||||
<PackageReference Include="DynamicData" Version="7.9.4" />
|
||||
<PackageReference Include="FluentAvaloniaUI" Version="1.4.1" />
|
||||
<PackageReference Include="XamlNameReferenceGenerator" Version="1.3.4" />
|
||||
|
||||
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" />
|
||||
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build10" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" />
|
||||
@ -118,6 +119,7 @@
|
||||
<None Remove="Assets\Locales\ru_RU.json" />
|
||||
<None Remove="Assets\Locales\tr_TR.json" />
|
||||
<None Remove="Assets\Locales\zh_CN.json" />
|
||||
<None Remove="Assets\Locales\zh_TW.json" />
|
||||
<None Remove="Assets\Styles\Styles.xaml" />
|
||||
<None Remove="Assets\Styles\BaseDark.xaml" />
|
||||
<None Remove="Assets\Styles\BaseLight.xaml" />
|
||||
@ -135,6 +137,7 @@
|
||||
<EmbeddedResource Include="Assets\Locales\ru_RU.json" />
|
||||
<EmbeddedResource Include="Assets\Locales\tr_TR.json" />
|
||||
<EmbeddedResource Include="Assets\Locales\zh_CN.json" />
|
||||
<EmbeddedResource Include="Assets\Locales\zh_TW.json" />
|
||||
<EmbeddedResource Include="Assets\Styles\Styles.xaml" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -92,7 +92,7 @@ namespace Ryujinx.Ava.Ui.Applet
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(_parent, string.Format(LocaleManager.Instance["DialogMessageDialogErrorExceptionMessage"], ex));
|
||||
await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogMessageDialogErrorExceptionMessage"], ex));
|
||||
|
||||
dialogCloseEvent.Set();
|
||||
}
|
||||
@ -126,7 +126,7 @@ namespace Ryujinx.Ava.Ui.Applet
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = true;
|
||||
await ContentDialogHelper.CreateErrorDialog(_parent, string.Format(LocaleManager.Instance["DialogSoftwareKeyboardErrorExceptionMessage"], ex));
|
||||
await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogSoftwareKeyboardErrorExceptionMessage"], ex));
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -181,7 +181,7 @@ namespace Ryujinx.Ava.Ui.Applet
|
||||
catch (Exception ex)
|
||||
{
|
||||
dialogCloseEvent.Set();
|
||||
await ContentDialogHelper.CreateErrorDialog(_parent, string.Format(LocaleManager.Instance["DialogErrorAppletErrorExceptionMessage"], ex));
|
||||
await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogErrorAppletErrorExceptionMessage"], ex));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Applet
|
||||
{
|
||||
internal class ErrorAppletWindow : StyleableWindow
|
||||
internal partial class ErrorAppletWindow : StyleableWindow
|
||||
{
|
||||
private readonly Window _owner;
|
||||
private object _buttonResponse;
|
||||
@ -50,8 +50,6 @@ namespace Ryujinx.Ava.Ui.Applet
|
||||
|
||||
public string Message { get; set; }
|
||||
|
||||
public StackPanel ButtonStack { get; set; }
|
||||
|
||||
private void AddButton(string label, object tag)
|
||||
{
|
||||
Dispatcher.UIThread.InvokeAsync(() =>
|
||||
@ -79,11 +77,5 @@ namespace Ryujinx.Ava.Ui.Applet
|
||||
|
||||
return _buttonResponse;
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
ButtonStack = this.FindControl<StackPanel>("ButtonStack");
|
||||
}
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
internal class SwkbdAppletDialog : UserControl
|
||||
internal partial class SwkbdAppletDialog : UserControl
|
||||
{
|
||||
private Predicate<int> _checkLength;
|
||||
private int _inputMax;
|
||||
@ -30,6 +30,10 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
_placeholder = placeholder;
|
||||
InitializeComponent();
|
||||
|
||||
Input.Watermark = _placeholder;
|
||||
|
||||
Input.AddHandler(TextInputEvent, Message_TextInput, RoutingStrategies.Tunnel, true);
|
||||
|
||||
SetInputLengthValidation(0, int.MaxValue); // Disable by default.
|
||||
}
|
||||
|
||||
@ -43,23 +47,9 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
public string MainText { get; set; } = "";
|
||||
public string SecondaryText { get; set; } = "";
|
||||
|
||||
public TextBlock Error { get; private set; }
|
||||
public TextBox Input { get; set; }
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
Error = this.FindControl<TextBlock>("Error");
|
||||
Input = this.FindControl<TextBox>("Input");
|
||||
|
||||
Input.Watermark = _placeholder;
|
||||
|
||||
Input.AddHandler(TextInputEvent, Message_TextInput, RoutingStrategies.Tunnel, true);
|
||||
}
|
||||
|
||||
public static async Task<(UserResult Result, string Input)> ShowInputDialog(StyleableWindow window, string title, SoftwareKeyboardUiArgs args)
|
||||
{
|
||||
ContentDialog contentDialog = window.ContentDialog;
|
||||
ContentDialog contentDialog = new ContentDialog();
|
||||
|
||||
UserResult result = UserResult.Cancel;
|
||||
|
||||
|
@ -16,7 +16,6 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
private static bool _isChoiceDialogOpen;
|
||||
|
||||
private async static Task<UserResult> ShowContentDialog(
|
||||
StyleableWindow window,
|
||||
string title,
|
||||
string primaryText,
|
||||
string secondaryText,
|
||||
@ -28,13 +27,11 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
UserResult result = UserResult.None;
|
||||
|
||||
ContentDialog contentDialog = window.ContentDialog;
|
||||
ContentDialog contentDialog = new ContentDialog();
|
||||
|
||||
await ShowDialog();
|
||||
|
||||
async Task ShowDialog()
|
||||
{
|
||||
if (contentDialog != null)
|
||||
{
|
||||
contentDialog.Title = title;
|
||||
contentDialog.PrimaryButtonText = primaryButton;
|
||||
@ -56,7 +53,6 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
});
|
||||
|
||||
await contentDialog.ShowAsync(ContentDialogPlacement.Popup);
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -78,23 +74,18 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
|
||||
UserResult result = UserResult.None;
|
||||
|
||||
ContentDialog contentDialog = window.ContentDialog;
|
||||
|
||||
Window overlay = window;
|
||||
|
||||
if (contentDialog != null)
|
||||
ContentDialog contentDialog = new ContentDialog
|
||||
{
|
||||
contentDialog.PrimaryButtonClick += DeferClose;
|
||||
contentDialog.Title = title;
|
||||
contentDialog.PrimaryButtonText = primaryButton;
|
||||
contentDialog.SecondaryButtonText = secondaryButton;
|
||||
contentDialog.CloseButtonText = closeButton;
|
||||
contentDialog.Content = CreateDialogTextContent(primaryText, secondaryText, iconSymbol);
|
||||
|
||||
contentDialog.PrimaryButtonCommand = MiniCommand.Create(() =>
|
||||
Title = title,
|
||||
PrimaryButtonText = primaryButton,
|
||||
SecondaryButtonText = secondaryButton,
|
||||
CloseButtonText = closeButton,
|
||||
Content = CreateDialogTextContent(primaryText, secondaryText, iconSymbol),
|
||||
PrimaryButtonCommand = MiniCommand.Create(() =>
|
||||
{
|
||||
result = primaryButton == LocaleManager.Instance["InputDialogYes"] ? UserResult.Yes : UserResult.Ok;
|
||||
});
|
||||
}),
|
||||
};
|
||||
contentDialog.SecondaryButtonCommand = MiniCommand.Create(() =>
|
||||
{
|
||||
contentDialog.PrimaryButtonClick -= DeferClose;
|
||||
@ -105,8 +96,8 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
contentDialog.PrimaryButtonClick -= DeferClose;
|
||||
result = UserResult.Cancel;
|
||||
});
|
||||
contentDialog.PrimaryButtonClick += DeferClose;
|
||||
await contentDialog.ShowAsync(ContentDialogPlacement.Popup);
|
||||
};
|
||||
|
||||
return result;
|
||||
|
||||
@ -141,7 +132,7 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
|
||||
if (doWhileDeferred != null)
|
||||
{
|
||||
await doWhileDeferred(overlay);
|
||||
await doWhileDeferred(window);
|
||||
|
||||
deferResetEvent.Set();
|
||||
}
|
||||
@ -191,7 +182,6 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
}
|
||||
|
||||
public static async Task<UserResult> CreateInfoDialog(
|
||||
StyleableWindow window,
|
||||
string primary,
|
||||
string secondaryText,
|
||||
string acceptButton,
|
||||
@ -199,7 +189,6 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
string title)
|
||||
{
|
||||
return await ShowContentDialog(
|
||||
window,
|
||||
title,
|
||||
primary,
|
||||
secondaryText,
|
||||
@ -210,7 +199,6 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
}
|
||||
|
||||
internal static async Task<UserResult> CreateConfirmationDialog(
|
||||
StyleableWindow window,
|
||||
string primaryText,
|
||||
string secondaryText,
|
||||
string acceptButtonText,
|
||||
@ -219,7 +207,6 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
UserResult primaryButtonResult = UserResult.Yes)
|
||||
{
|
||||
return await ShowContentDialog(
|
||||
window,
|
||||
string.IsNullOrWhiteSpace(title) ? LocaleManager.Instance["DialogConfirmationTitle"] : title,
|
||||
primaryText,
|
||||
secondaryText,
|
||||
@ -235,10 +222,9 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
return new(mainText, secondaryText);
|
||||
}
|
||||
|
||||
internal static async Task CreateUpdaterInfoDialog(StyleableWindow window, string primary, string secondaryText)
|
||||
internal static async Task CreateUpdaterInfoDialog(string primary, string secondaryText)
|
||||
{
|
||||
await ShowContentDialog(
|
||||
window,
|
||||
LocaleManager.Instance["DialogUpdaterTitle"],
|
||||
primary,
|
||||
secondaryText,
|
||||
@ -248,24 +234,9 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
(int)Symbol.Important);
|
||||
}
|
||||
|
||||
internal static async Task ShowNotAvailableMessage(StyleableWindow window)
|
||||
{
|
||||
// Temporary placeholder for features to be added
|
||||
await ShowContentDialog(
|
||||
window,
|
||||
"Feature Not Available",
|
||||
"The selected feature is not available in this version.",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
LocaleManager.Instance["InputDialogOk"],
|
||||
(int)Symbol.Important);
|
||||
}
|
||||
|
||||
internal static async Task CreateWarningDialog(StyleableWindow window, string primary, string secondaryText)
|
||||
internal static async Task CreateWarningDialog(string primary, string secondaryText)
|
||||
{
|
||||
await ShowContentDialog(
|
||||
window,
|
||||
LocaleManager.Instance["DialogWarningTitle"],
|
||||
primary,
|
||||
secondaryText,
|
||||
@ -275,12 +246,11 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
(int)Symbol.Important);
|
||||
}
|
||||
|
||||
internal static async Task CreateErrorDialog(StyleableWindow owner, string errorMessage, string secondaryErrorMessage = "")
|
||||
internal static async Task CreateErrorDialog(string errorMessage, string secondaryErrorMessage = "")
|
||||
{
|
||||
Logger.Error?.Print(LogClass.Application, errorMessage);
|
||||
|
||||
await ShowContentDialog(
|
||||
owner,
|
||||
LocaleManager.Instance["DialogErrorTitle"],
|
||||
LocaleManager.Instance["DialogErrorMessage"],
|
||||
errorMessage,
|
||||
@ -290,7 +260,7 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
(int)Symbol.Dismiss);
|
||||
}
|
||||
|
||||
internal static async Task<bool> CreateChoiceDialog(StyleableWindow window, string title, string primary, string secondaryText)
|
||||
internal static async Task<bool> CreateChoiceDialog(string title, string primary, string secondaryText)
|
||||
{
|
||||
if (_isChoiceDialogOpen)
|
||||
{
|
||||
@ -301,7 +271,6 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
|
||||
UserResult response =
|
||||
await ShowContentDialog(
|
||||
window,
|
||||
title,
|
||||
primary,
|
||||
secondaryText,
|
||||
@ -316,19 +285,17 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
return response == UserResult.Yes;
|
||||
}
|
||||
|
||||
internal static async Task<bool> CreateExitDialog(StyleableWindow owner)
|
||||
internal static async Task<bool> CreateExitDialog()
|
||||
{
|
||||
return await CreateChoiceDialog(
|
||||
owner,
|
||||
LocaleManager.Instance["DialogExitTitle"],
|
||||
LocaleManager.Instance["DialogExitMessage"],
|
||||
LocaleManager.Instance["DialogExitSubMessage"]);
|
||||
}
|
||||
|
||||
internal static async Task<bool> CreateStopEmulationDialog(StyleableWindow owner)
|
||||
internal static async Task<bool> CreateStopEmulationDialog()
|
||||
{
|
||||
return await CreateChoiceDialog(
|
||||
owner,
|
||||
LocaleManager.Instance["DialogStopEmulationTitle"],
|
||||
LocaleManager.Instance["DialogStopEmulationMessage"],
|
||||
LocaleManager.Instance["DialogExitSubMessage"]);
|
||||
@ -338,12 +305,10 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
string title,
|
||||
string mainText,
|
||||
string subText,
|
||||
StyleableWindow owner,
|
||||
uint maxLength = int.MaxValue,
|
||||
string input = "")
|
||||
{
|
||||
var result = await InputDialog.ShowInputDialog(
|
||||
owner,
|
||||
title,
|
||||
mainText,
|
||||
input,
|
||||
|
@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
public class InputDialog : UserControl
|
||||
public partial class InputDialog : UserControl
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public string Input { get; set; }
|
||||
@ -24,8 +24,6 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
MaxLength = maxLength;
|
||||
|
||||
DataContext = this;
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public InputDialog()
|
||||
@ -33,33 +31,26 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
public static async Task<(UserResult Result, string Input)> ShowInputDialog(string title, string message,
|
||||
string input = "", string subMessage = "", uint maxLength = int.MaxValue)
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public static async Task<(UserResult Result, string Input)> ShowInputDialog(StyleableWindow window, string title, string message, string input = "", string subMessage = "", uint maxLength = int.MaxValue)
|
||||
{
|
||||
ContentDialog contentDialog = window.ContentDialog;
|
||||
|
||||
UserResult result = UserResult.Cancel;
|
||||
|
||||
InputDialog content = new InputDialog(message, input = "", subMessage = "", maxLength);
|
||||
|
||||
if (contentDialog != null)
|
||||
InputDialog content = new InputDialog(message, input, subMessage, maxLength);
|
||||
ContentDialog contentDialog = new ContentDialog
|
||||
{
|
||||
contentDialog.Title = title;
|
||||
contentDialog.PrimaryButtonText = LocaleManager.Instance["InputDialogOk"];
|
||||
contentDialog.SecondaryButtonText = "";
|
||||
contentDialog.CloseButtonText = LocaleManager.Instance["InputDialogCancel"];
|
||||
contentDialog.Content = content;
|
||||
contentDialog.PrimaryButtonCommand = MiniCommand.Create(() =>
|
||||
Title = title,
|
||||
PrimaryButtonText = LocaleManager.Instance["InputDialogOk"],
|
||||
SecondaryButtonText = "",
|
||||
CloseButtonText = LocaleManager.Instance["InputDialogCancel"],
|
||||
Content = content,
|
||||
PrimaryButtonCommand = MiniCommand.Create(() =>
|
||||
{
|
||||
result = UserResult.Ok;
|
||||
input = content.Input;
|
||||
});
|
||||
})
|
||||
};
|
||||
await contentDialog.ShowAsync();
|
||||
}
|
||||
|
||||
return (result, input);
|
||||
}
|
||||
|
10
Ryujinx.Ava/Ui/Controls/NavigationDialogHost.axaml
Normal file
10
Ryujinx.Ava/Ui/Controls/NavigationDialogHost.axaml
Normal file
@ -0,0 +1,10 @@
|
||||
<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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Ryujinx.Ava.Ui.Controls.NavigationDialogHost">
|
||||
<ui:Frame HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
|
||||
x:Name="ContentFrame" />
|
||||
</UserControl>
|
85
Ryujinx.Ava/Ui/Controls/NavigationDialogHost.axaml.cs
Normal file
85
Ryujinx.Ava/Ui/Controls/NavigationDialogHost.axaml.cs
Normal file
@ -0,0 +1,85 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Ui.ViewModels;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
public partial class NavigationDialogHost : UserControl
|
||||
{
|
||||
public AccountManager AccountManager { get; }
|
||||
public ContentManager ContentManager { get; }
|
||||
public UserProfileViewModel ViewModel { get; set; }
|
||||
|
||||
public NavigationDialogHost()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public NavigationDialogHost(AccountManager accountManager, ContentManager contentManager,
|
||||
VirtualFileSystem virtualFileSystem)
|
||||
{
|
||||
AccountManager = accountManager;
|
||||
ContentManager = contentManager;
|
||||
ViewModel = new UserProfileViewModel(this);
|
||||
|
||||
|
||||
if (contentManager.GetCurrentFirmwareVersion() != null)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
AvatarProfileViewModel.PreloadAvatars(contentManager, virtualFileSystem);
|
||||
});
|
||||
}
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void GoBack(object parameter = null)
|
||||
{
|
||||
if (ContentFrame.BackStack.Count > 0)
|
||||
{
|
||||
ContentFrame.GoBack();
|
||||
}
|
||||
|
||||
ViewModel.LoadProfiles();
|
||||
}
|
||||
|
||||
public void Navigate(Type sourcePageType, object parameter)
|
||||
{
|
||||
ContentFrame.Navigate(sourcePageType, parameter);
|
||||
}
|
||||
|
||||
public static async Task Show(AccountManager ownerAccountManager, ContentManager ownerContentManager, VirtualFileSystem ownerVirtualFileSystem)
|
||||
{
|
||||
var content = new NavigationDialogHost(ownerAccountManager, ownerContentManager, ownerVirtualFileSystem);
|
||||
ContentDialog contentDialog = new ContentDialog
|
||||
{
|
||||
Title = LocaleManager.Instance["UserProfileWindowTitle"],
|
||||
PrimaryButtonText = "",
|
||||
SecondaryButtonText = "",
|
||||
CloseButtonText = LocaleManager.Instance["UserProfilesClose"],
|
||||
Content = content,
|
||||
Padding = new Thickness(0)
|
||||
};
|
||||
|
||||
contentDialog.Closed += (sender, args) =>
|
||||
{
|
||||
content.ViewModel.Dispose();
|
||||
};
|
||||
|
||||
await contentDialog.ShowAsync();
|
||||
}
|
||||
|
||||
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnAttachedToVisualTree(e);
|
||||
|
||||
Navigate(typeof(UserSelector), this);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +1,10 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
<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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
xmlns:Locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
||||
x:Class="Ryujinx.Ava.Ui.Controls.ProfileImageSelectionDialog"
|
||||
SizeToContent="WidthAndHeight"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Title="{Locale:Locale ProfileImageSelectionTitle}"
|
||||
CanResize="false">
|
||||
x:Class="Ryujinx.Ava.Ui.Controls.ProfileImageSelectionDialog">
|
||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="5,10,5, 5">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@ -32,4 +28,4 @@
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
</UserControl>
|
@ -1,8 +1,10 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.VisualTree;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using FluentAvalonia.UI.Navigation;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Ui.Models;
|
||||
using Ryujinx.Ava.Ui.Windows;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using SixLabors.ImageSharp;
|
||||
@ -12,36 +14,40 @@ using Image = SixLabors.ImageSharp.Image;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
public class ProfileImageSelectionDialog : StyleableWindow
|
||||
public partial class ProfileImageSelectionDialog : UserControl
|
||||
{
|
||||
private readonly ContentManager _contentManager;
|
||||
private ContentManager _contentManager;
|
||||
private NavigationDialogHost _parent;
|
||||
private TempProfile _profile;
|
||||
|
||||
public bool FirmwareFound => _contentManager.GetCurrentFirmwareVersion() != null;
|
||||
|
||||
public byte[] BufferImageProfile { get; set; }
|
||||
|
||||
public ProfileImageSelectionDialog(ContentManager contentManager)
|
||||
{
|
||||
_contentManager = contentManager;
|
||||
DataContext = this;
|
||||
InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
}
|
||||
|
||||
public ProfileImageSelectionDialog()
|
||||
{
|
||||
DataContext = this;
|
||||
InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
AddHandler(Frame.NavigatedToEvent, (s, e) =>
|
||||
{
|
||||
NavigatedTo(e);
|
||||
}, RoutingStrategies.Direct);
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
private void NavigatedTo(NavigationEventArgs arg)
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
if (Program.PreviewerDetached)
|
||||
{
|
||||
switch (arg.NavigationMode)
|
||||
{
|
||||
case NavigationMode.New:
|
||||
(_parent, _profile) = ((NavigationDialogHost, TempProfile))arg.Parameter;
|
||||
_contentManager = _parent.ContentManager;
|
||||
break;
|
||||
case NavigationMode.Back:
|
||||
_parent.GoBack();
|
||||
break;
|
||||
}
|
||||
|
||||
DataContext = this;
|
||||
}
|
||||
}
|
||||
|
||||
private async void Import_OnClick(object sender, RoutedEventArgs e)
|
||||
@ -58,7 +64,7 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
|
||||
dialog.AllowMultiple = false;
|
||||
|
||||
string[] image = await dialog.ShowAsync(this);
|
||||
string[] image = await dialog.ShowAsync(((TopLevel)_parent.GetVisualRoot()) as Window);
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
@ -66,28 +72,22 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
string imageFile = image[0];
|
||||
|
||||
ProcessProfileImage(File.ReadAllBytes(imageFile));
|
||||
_profile.Image = ProcessProfileImage(File.ReadAllBytes(imageFile));
|
||||
}
|
||||
|
||||
Close();
|
||||
_parent.GoBack();
|
||||
}
|
||||
}
|
||||
|
||||
private async void SelectFirmwareImage_OnClick(object sender, RoutedEventArgs e)
|
||||
private void SelectFirmwareImage_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (FirmwareFound)
|
||||
{
|
||||
AvatarWindow window = new(_contentManager);
|
||||
|
||||
await window.ShowDialog(this);
|
||||
|
||||
BufferImageProfile = window.SelectedImage;
|
||||
|
||||
Close();
|
||||
_parent.Navigate(typeof(AvatarWindow), (_parent, _profile));
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessProfileImage(byte[] buffer)
|
||||
private static byte[] ProcessProfileImage(byte[] buffer)
|
||||
{
|
||||
using (Image image = Image.Load(buffer))
|
||||
{
|
||||
@ -97,7 +97,7 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
image.SaveAsJpeg(streamJpg);
|
||||
|
||||
BufferImageProfile = streamJpg.ToArray();
|
||||
return streamJpg.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ using Ryujinx.Ava.Ui.Windows;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
public class UpdateWaitWindow : StyleableWindow
|
||||
public partial class UpdateWaitWindow : StyleableWindow
|
||||
{
|
||||
public UpdateWaitWindow(string primaryText, string secondaryText) : this()
|
||||
{
|
||||
@ -21,15 +21,5 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
}
|
||||
|
||||
public TextBlock PrimaryText { get; private set; }
|
||||
public TextBlock SecondaryText { get; private set; }
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
PrimaryText = this.FindControl<TextBlock>("PrimaryText");
|
||||
SecondaryText = this.FindControl<TextBlock>("SecondaryText");
|
||||
}
|
||||
}
|
||||
}
|
55
Ryujinx.Ava/Ui/Controls/UserEditor.axaml
Normal file
55
Ryujinx.Ava/Ui/Controls/UserEditor.axaml
Normal file
@ -0,0 +1,55 @@
|
||||
<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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Padding="0"
|
||||
Margin="0"
|
||||
xmlns:Locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels"
|
||||
xmlns:models="clr-namespace:Ryujinx.Ava.Ui.Models"
|
||||
xmlns:controls="clr-namespace:Ryujinx.Ava.Ui.Controls"
|
||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
x:Class="Ryujinx.Ava.Ui.Controls.UserEditor">
|
||||
<UserControl.Resources>
|
||||
<controls:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Left">
|
||||
<Image
|
||||
Margin="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
Height="96" Width="96"
|
||||
Name="ProfileImage"
|
||||
Source="{Binding Image, Converter={StaticResource ByteImage}}" />
|
||||
<Button Margin="5" Content="{Locale:Locale UserProfilesChangeProfileImage}"
|
||||
Name="ChangePictureButton"
|
||||
Click="ChangePictureButton_Click"
|
||||
HorizontalAlignment="Stretch"/>
|
||||
<Button Margin="5" Content="{Locale:Locale UserProfilesSetProfileImage}"
|
||||
Name="AddPictureButton"
|
||||
Click="ChangePictureButton_Click"
|
||||
HorizontalAlignment="Stretch"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Orientation="Vertical" HorizontalAlignment="Stretch" Grid.Column="1" Spacing="10"
|
||||
Margin="5, 10">
|
||||
<TextBox Name="NameBox" Width="300" Text="{Binding Name}" MaxLength="{Binding MaxProfileNameLength}"
|
||||
HorizontalAlignment="Stretch" />
|
||||
<TextBlock Text="{Binding UserId}" Name="IdLabel" />
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Orientation="Horizontal" Spacing="10" HorizontalAlignment="Right">
|
||||
<Button Content="{Locale:Locale Save}" Name="SaveButton" Click="SaveButton_Click"/>
|
||||
<Button HorizontalAlignment="Right" Content="{Locale:Locale Discard}"
|
||||
Name="CloseButton" Click="CloseButton_Click"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
123
Ryujinx.Ava/Ui/Controls/UserEditor.axaml.cs
Normal file
123
Ryujinx.Ava/Ui/Controls/UserEditor.axaml.cs
Normal file
@ -0,0 +1,123 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Interactivity;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using FluentAvalonia.UI.Navigation;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Ui.Models;
|
||||
using UserProfile = Ryujinx.Ava.Ui.Models.UserProfile;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
public partial class UserEditor : UserControl
|
||||
{
|
||||
private NavigationDialogHost _parent;
|
||||
private UserProfile _profile;
|
||||
private bool _isNewUser;
|
||||
|
||||
public TempProfile TempProfile { get; set; }
|
||||
public uint MaxProfileNameLength => 0x20;
|
||||
|
||||
public UserEditor()
|
||||
{
|
||||
InitializeComponent();
|
||||
AddHandler(Frame.NavigatedToEvent, (s, e) =>
|
||||
{
|
||||
NavigatedTo(e);
|
||||
}, RoutingStrategies.Direct);
|
||||
}
|
||||
|
||||
private void NavigatedTo(NavigationEventArgs arg)
|
||||
{
|
||||
if (Program.PreviewerDetached)
|
||||
{
|
||||
switch (arg.NavigationMode)
|
||||
{
|
||||
case NavigationMode.New:
|
||||
var args = ((NavigationDialogHost parent, UserProfile profile, bool isNewUser))arg.Parameter;
|
||||
_isNewUser = args.isNewUser;
|
||||
if (!_isNewUser)
|
||||
{
|
||||
_profile = args.profile;
|
||||
TempProfile = new TempProfile(_profile);
|
||||
}
|
||||
else
|
||||
{
|
||||
TempProfile = new TempProfile();
|
||||
}
|
||||
|
||||
_parent = args.parent;
|
||||
break;
|
||||
}
|
||||
|
||||
DataContext = TempProfile;
|
||||
|
||||
AddPictureButton.IsVisible = _isNewUser;
|
||||
IdLabel.IsVisible = !_isNewUser;
|
||||
ChangePictureButton.IsVisible = !_isNewUser;
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_parent?.GoBack();
|
||||
}
|
||||
|
||||
private void SaveButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DataValidationErrors.ClearErrors(NameBox);
|
||||
bool isInvalid = false;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(TempProfile.Name))
|
||||
{
|
||||
DataValidationErrors.SetError(NameBox, new DataValidationException(LocaleManager.Instance["UserProfileEmptyNameError"]));
|
||||
|
||||
isInvalid = true;
|
||||
}
|
||||
|
||||
if (TempProfile.Image == null)
|
||||
{
|
||||
ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance["UserProfileNoImageError"], "");
|
||||
|
||||
isInvalid = true;
|
||||
}
|
||||
|
||||
if(isInvalid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_profile != null)
|
||||
{
|
||||
_profile.Name = TempProfile.Name;
|
||||
_profile.Image = TempProfile.Image;
|
||||
_profile.UpdateState();
|
||||
_parent.AccountManager.SetUserName(_profile.UserId, _profile.Name);
|
||||
_parent.AccountManager.SetUserImage(_profile.UserId, _profile.Image);
|
||||
}
|
||||
else if (_isNewUser)
|
||||
{
|
||||
_parent.AccountManager.AddUser(TempProfile.Name, TempProfile.Image);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_parent?.GoBack();
|
||||
}
|
||||
|
||||
public void SelectProfileImage()
|
||||
{
|
||||
_parent.Navigate(typeof(ProfileImageSelectionDialog), (_parent, TempProfile));
|
||||
}
|
||||
|
||||
private void ChangePictureButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_profile != null || _isNewUser)
|
||||
{
|
||||
SelectProfileImage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -75,7 +75,7 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
|
||||
string setupButtonLabel = isInSetupGuide ? LocaleManager.Instance["OpenSetupGuideMessage"] : "";
|
||||
|
||||
var result = await ContentDialogHelper.CreateInfoDialog(owner,
|
||||
var result = await ContentDialogHelper.CreateInfoDialog(
|
||||
string.Format(LocaleManager.Instance["DialogUserErrorDialogMessage"], errorCode, GetErrorTitle(error)),
|
||||
GetErrorDescription(error) + (isInSetupGuide
|
||||
? LocaleManager.Instance["DialogUserErrorDialogInfoMessage"]
|
||||
|
90
Ryujinx.Ava/Ui/Controls/UserSelector.axaml
Normal file
90
Ryujinx.Ava/Ui/Controls/UserSelector.axaml
Normal file
@ -0,0 +1,90 @@
|
||||
<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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:flex="clr-namespace:Avalonia.Flexbox;assembly=Avalonia.Flexbox"
|
||||
xmlns:Locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels"
|
||||
xmlns:controls="clr-namespace:Ryujinx.Ava.Ui.Controls"
|
||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Ryujinx.Ava.Ui.Controls.UserSelector">
|
||||
<UserControl.Resources>
|
||||
<controls:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||
</UserControl.Resources>
|
||||
<Design.DataContext>
|
||||
<viewModels:UserProfileViewModel />
|
||||
</Design.DataContext>
|
||||
<Grid HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ListBox HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="5" Items="{Binding Profiles}"
|
||||
DoubleTapped="ProfilesList_DoubleTapped"
|
||||
SelectionChanged="SelectingItemsControl_SelectionChanged">
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<flex:FlexPanel
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
AlignContent="FlexStart"
|
||||
JustifyContent="Center" />
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<Border
|
||||
Margin="2"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
ClipToBounds="True"
|
||||
CornerRadius="5">
|
||||
<Grid Margin="0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Image
|
||||
Grid.Row="0"
|
||||
Margin="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
Height="96" Width="96"
|
||||
Source="{Binding Image, Converter={StaticResource ByteImage}}" />
|
||||
<StackPanel
|
||||
Grid.Row="1"
|
||||
Height="30"
|
||||
Margin="5"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Stretch"
|
||||
Text="{Binding Name}"
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
<Border HorizontalAlignment="Left" VerticalAlignment="Top"
|
||||
IsVisible="{Binding IsOpened}"
|
||||
Background="LimeGreen"
|
||||
Width="10"
|
||||
Height="10"
|
||||
Margin="5"
|
||||
CornerRadius="5" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="10,0" Spacing="10" HorizontalAlignment="Center">
|
||||
<Button Content="{Locale:Locale UserProfilesAddNewProfile}" Command="{Binding AddUser}" />
|
||||
<Button IsEnabled="{Binding IsSelectedProfiledEditable}"
|
||||
Content="{Locale:Locale UserProfilesEditProfile}" Command="{Binding EditUser}" />
|
||||
<Button IsEnabled="{Binding IsSelectedProfileDeletable}"
|
||||
Content="{Locale:Locale UserProfilesDeleteSelectedProfile}" Command="{Binding DeleteUser}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
79
Ryujinx.Ava/Ui/Controls/UserSelector.axaml.cs
Normal file
79
Ryujinx.Ava/Ui/Controls/UserSelector.axaml.cs
Normal file
@ -0,0 +1,79 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using FluentAvalonia.UI.Navigation;
|
||||
using Ryujinx.Ava.Ui.ViewModels;
|
||||
using UserProfile = Ryujinx.Ava.Ui.Models.UserProfile;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
public partial class UserSelector : UserControl
|
||||
{
|
||||
private NavigationDialogHost _parent;
|
||||
public UserProfileViewModel ViewModel { get; set; }
|
||||
|
||||
public UserSelector()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
if (Program.PreviewerDetached)
|
||||
{
|
||||
AddHandler(Frame.NavigatedToEvent, (s, e) =>
|
||||
{
|
||||
NavigatedTo(e);
|
||||
}, Avalonia.Interactivity.RoutingStrategies.Direct);
|
||||
}
|
||||
}
|
||||
|
||||
private void NavigatedTo(NavigationEventArgs arg)
|
||||
{
|
||||
if (Program.PreviewerDetached)
|
||||
{
|
||||
switch (arg.NavigationMode)
|
||||
{
|
||||
case NavigationMode.New:
|
||||
_parent = (NavigationDialogHost)arg.Parameter;
|
||||
ViewModel = _parent.ViewModel;
|
||||
break;
|
||||
}
|
||||
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProfilesList_DoubleTapped(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is ListBox listBox)
|
||||
{
|
||||
int selectedIndex = listBox.SelectedIndex;
|
||||
|
||||
if (selectedIndex >= 0 && selectedIndex < ViewModel.Profiles.Count)
|
||||
{
|
||||
ViewModel.SelectedProfile = ViewModel.Profiles[selectedIndex];
|
||||
|
||||
_parent?.AccountManager?.OpenUser(ViewModel.SelectedProfile.UserId);
|
||||
|
||||
ViewModel.LoadProfiles();
|
||||
|
||||
foreach (UserProfile profile in ViewModel.Profiles)
|
||||
{
|
||||
profile.UpdateState();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectingItemsControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (sender is ListBox listBox)
|
||||
{
|
||||
int selectedIndex = listBox.SelectedIndex;
|
||||
|
||||
if (selectedIndex >= 0 && selectedIndex < ViewModel.Profiles.Count)
|
||||
{
|
||||
ViewModel.HighlightedProfile = ViewModel.Profiles[selectedIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
55
Ryujinx.Ava/Ui/Models/TempProfile.cs
Normal file
55
Ryujinx.Ava/Ui/Models/TempProfile.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using Ryujinx.Ava.Ui.ViewModels;
|
||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Models
|
||||
{
|
||||
public class TempProfile : BaseModel
|
||||
{
|
||||
private readonly UserProfile _profile;
|
||||
private byte[] _image = null;
|
||||
private string _name = String.Empty;
|
||||
private UserId _userId;
|
||||
|
||||
public byte[] Image
|
||||
{
|
||||
get => _image;
|
||||
set
|
||||
{
|
||||
_image = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public UserId UserId
|
||||
{
|
||||
get => _userId;
|
||||
set
|
||||
{
|
||||
_userId = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set
|
||||
{
|
||||
_name = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public TempProfile(UserProfile profile)
|
||||
{
|
||||
_profile = profile;
|
||||
|
||||
Image = profile.Image;
|
||||
Name = profile.Name;
|
||||
UserId = profile.UserId;
|
||||
}
|
||||
|
||||
public TempProfile(){}
|
||||
}
|
||||
}
|
@ -390,7 +390,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
return amiiboJsonString;
|
||||
}
|
||||
|
||||
await ContentDialogHelper.CreateInfoDialog(_owner, LocaleManager.Instance["DialogAmiiboApiTitle"],
|
||||
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance["DialogAmiiboApiTitle"],
|
||||
LocaleManager.Instance["DialogAmiiboApiFailFetchMessage"],
|
||||
LocaleManager.Instance["InputDialogOk"],
|
||||
"",
|
||||
@ -440,7 +440,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
|
||||
private async void ShowInfoDialog()
|
||||
{
|
||||
await ContentDialogHelper.CreateInfoDialog(_owner, LocaleManager.Instance["DialogAmiiboApiTitle"],
|
||||
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance["DialogAmiiboApiTitle"],
|
||||
LocaleManager.Instance["DialogAmiiboApiConnectErrorMessage"],
|
||||
LocaleManager.Instance["InputDialogOk"],
|
||||
"",
|
||||
|
@ -327,12 +327,12 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
|
||||
public async void ShowMotionConfig()
|
||||
{
|
||||
await MotionSettingsWindow.Show(this, _owner.GetVisualRoot() as StyleableWindow);
|
||||
await MotionSettingsWindow.Show(this);
|
||||
}
|
||||
|
||||
public async void ShowRumbleConfig()
|
||||
{
|
||||
await RumbleSettingsWindow.Show(this, _owner.GetVisualRoot() as StyleableWindow);
|
||||
await RumbleSettingsWindow.Show(this);
|
||||
}
|
||||
|
||||
private void LoadInputDriver()
|
||||
@ -701,8 +701,8 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
Logger.Error?.Print(LogClass.Configuration, $"Profile {ProfileName} is incompatible with the current input configuration system.");
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner.GetVisualRoot() as StyleableWindow,
|
||||
String.Format(LocaleManager.Instance["DialogProfileInvalidProfileErrorMessage"], ProfileName));
|
||||
|
||||
await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogProfileInvalidProfileErrorMessage"], ProfileName));
|
||||
|
||||
return;
|
||||
}
|
||||
@ -736,7 +736,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
|
||||
if (ProfileName == LocaleManager.Instance["ControllerSettingsProfileDefault"])
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner.GetVisualRoot() as StyleableWindow, LocaleManager.Instance["DialogProfileDefaultProfileOverwriteErrorMessage"]);
|
||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogProfileDefaultProfileOverwriteErrorMessage"]);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -769,7 +769,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
}
|
||||
else
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner.GetVisualRoot() as StyleableWindow, LocaleManager.Instance["DialogProfileInvalidProfileNameErrorMessage"]);
|
||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogProfileInvalidProfileNameErrorMessage"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -782,7 +782,6 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
}
|
||||
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
|
||||
_owner.GetVisualRoot() as StyleableWindow,
|
||||
LocaleManager.Instance["DialogProfileDeleteProfileTitle"],
|
||||
LocaleManager.Instance["DialogProfileDeleteProfileMessage"],
|
||||
LocaleManager.Instance["InputDialogYes"],
|
||||
|
@ -975,9 +975,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
|
||||
public async void ManageProfiles()
|
||||
{
|
||||
UserProfileWindow window = new(_owner.AccountManager, _owner.ContentManager, _owner.VirtualFileSystem);
|
||||
|
||||
await window.ShowDialog(_owner);
|
||||
await NavigationDialogHost.Show(_owner.AccountManager, _owner.ContentManager, _owner.VirtualFileSystem);
|
||||
}
|
||||
|
||||
public async void OpenAboutWindow()
|
||||
@ -1054,8 +1052,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
{
|
||||
Dispatcher.UIThread.Post(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner,
|
||||
LocaleManager.Instance["DialogRyujinxErrorMessage"], LocaleManager.Instance["DialogInvalidTitleIdErrorMessage"]);
|
||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogRyujinxErrorMessage"], LocaleManager.Instance["DialogInvalidTitleIdErrorMessage"]);
|
||||
});
|
||||
|
||||
return;
|
||||
@ -1138,7 +1135,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
DirectoryInfo backupDir = new(Path.Combine(AppDataManager.GamesDirPath, selection.TitleId, "cache", "cpu", "1"));
|
||||
|
||||
// FIXME: Found a way to reproduce the bold effect on the title name (fork?).
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(_owner, LocaleManager.Instance["DialogWarning"],
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance["DialogWarning"],
|
||||
string.Format(LocaleManager.Instance["DialogPPTCDeletionMessage"], selection.TitleName), LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], LocaleManager.Instance["RyujinxConfirm"]);
|
||||
|
||||
List<FileInfo> cacheFiles = new();
|
||||
@ -1163,7 +1160,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner, string.Format(LocaleManager.Instance["DialogPPTCDeletionErrorMessage"], file.Name, e));
|
||||
await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogPPTCDeletionErrorMessage"], file.Name, e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1201,7 +1198,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
DirectoryInfo shaderCacheDir = new(Path.Combine(AppDataManager.GamesDirPath, selection.TitleId, "cache", "shader"));
|
||||
|
||||
// FIXME: Found a way to reproduce the bold effect on the title name (fork?).
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(_owner, LocaleManager.Instance["DialogWarning"],
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance["DialogWarning"],
|
||||
string.Format(LocaleManager.Instance["DialogShaderDeletionMessage"], selection.TitleName), LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], LocaleManager.Instance["RyujinxConfirm"]);
|
||||
|
||||
List<DirectoryInfo> oldCacheDirectories = new List<DirectoryInfo>();
|
||||
@ -1224,7 +1221,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner, string.Format(LocaleManager.Instance["DialogPPTCDeletionErrorMessage"], directory.Name, e));
|
||||
await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogPPTCDeletionErrorMessage"], directory.Name, e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1237,7 +1234,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner, string.Format(LocaleManager.Instance["ShaderCachePurgeError"], file.Name, e));
|
||||
await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["ShaderCachePurgeError"], file.Name, e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1320,8 +1317,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
{
|
||||
Dispatcher.UIThread.Post(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner,
|
||||
LocaleManager.Instance["DialogRyujinxErrorMessage"], LocaleManager.Instance["DialogInvalidTitleIdErrorMessage"]);
|
||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogRyujinxErrorMessage"], LocaleManager.Instance["DialogInvalidTitleIdErrorMessage"]);
|
||||
});
|
||||
|
||||
return;
|
||||
@ -1346,8 +1342,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
{
|
||||
Dispatcher.UIThread.Post(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner,
|
||||
LocaleManager.Instance["DialogRyujinxErrorMessage"], LocaleManager.Instance["DialogInvalidTitleIdErrorMessage"]);
|
||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogRyujinxErrorMessage"], LocaleManager.Instance["DialogInvalidTitleIdErrorMessage"]);
|
||||
});
|
||||
|
||||
return;
|
||||
@ -1406,7 +1401,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
|
||||
if (firmwareVersion == null)
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner, string.Format(LocaleManager.Instance["DialogFirmwareInstallerFirmwareNotFoundErrorMessage"], filename));
|
||||
await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogFirmwareInstallerFirmwareNotFoundErrorMessage"], filename));
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1426,7 +1421,6 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
dialogMessage += LocaleManager.Instance["DialogFirmwareInstallerFirmwareInstallConfirmMessage"];
|
||||
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
|
||||
_owner,
|
||||
dialogTitle,
|
||||
dialogMessage,
|
||||
LocaleManager.Instance["InputDialogYes"],
|
||||
@ -1456,7 +1450,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
|
||||
string message = string.Format(LocaleManager.Instance["DialogFirmwareInstallerFirmwareInstallSuccessMessage"], firmwareVersion.VersionString);
|
||||
|
||||
await ContentDialogHelper.CreateInfoDialog(_owner, dialogTitle, message, LocaleManager.Instance["InputDialogOk"], "", LocaleManager.Instance["RyujinxInfo"]);
|
||||
await ContentDialogHelper.CreateInfoDialog(dialogTitle, message, LocaleManager.Instance["InputDialogOk"], "", LocaleManager.Instance["RyujinxInfo"]);
|
||||
Logger.Info?.Print(LogClass.Application, message);
|
||||
|
||||
// Purge Applet Cache.
|
||||
@ -1475,7 +1469,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
{
|
||||
waitingDialog.Close();
|
||||
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner, ex.Message);
|
||||
await ContentDialogHelper.CreateErrorDialog(ex.Message);
|
||||
});
|
||||
}
|
||||
finally
|
||||
@ -1496,7 +1490,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner, ex.Message);
|
||||
await ContentDialogHelper.CreateErrorDialog(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,8 +63,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
{
|
||||
Dispatcher.UIThread.Post(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateInfoDialog(_owner,
|
||||
LocaleManager.Instance["DialogSettingsBackendThreadingWarningMessage"],
|
||||
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance["DialogSettingsBackendThreadingWarningMessage"],
|
||||
"",
|
||||
"",
|
||||
LocaleManager.Instance["InputDialogOk"],
|
||||
|
@ -1,31 +1,27 @@
|
||||
using Avalonia.Threading;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Ui.Controls;
|
||||
using Ryujinx.Ava.Ui.Windows;
|
||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using UserProfile = Ryujinx.Ava.Ui.Models.UserProfile;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.ViewModels
|
||||
{
|
||||
public class UserProfileViewModel : BaseModel, IDisposable
|
||||
{
|
||||
private const uint MaxProfileNameLength = 0x20;
|
||||
|
||||
private readonly UserProfileWindow _owner;
|
||||
private readonly NavigationDialogHost _owner;
|
||||
|
||||
private UserProfile _selectedProfile;
|
||||
private string _tempUserName;
|
||||
private UserProfile _highlightedProfile;
|
||||
|
||||
public UserProfileViewModel()
|
||||
{
|
||||
Profiles = new ObservableCollection<UserProfile>();
|
||||
}
|
||||
|
||||
public UserProfileViewModel(UserProfileWindow owner) : this()
|
||||
public UserProfileViewModel(NavigationDialogHost owner) : this()
|
||||
{
|
||||
_owner = owner;
|
||||
|
||||
@ -42,12 +38,29 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
_selectedProfile = value;
|
||||
|
||||
OnPropertyChanged(nameof(SelectedProfile));
|
||||
OnPropertyChanged(nameof(IsSelectedProfileDeletable));
|
||||
OnPropertyChanged(nameof(IsHighlightedProfileDeletable));
|
||||
OnPropertyChanged(nameof(IsHighlightedProfileEditable));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSelectedProfileDeletable =>
|
||||
_selectedProfile != null && _selectedProfile.UserId != AccountManager.DefaultUserId;
|
||||
public bool IsHighlightedProfileEditable =>
|
||||
_highlightedProfile != null;
|
||||
|
||||
public bool IsHighlightedProfileDeletable =>
|
||||
_highlightedProfile != null && _highlightedProfile.UserId != AccountManager.DefaultUserId;
|
||||
|
||||
public UserProfile HighlightedProfile
|
||||
{
|
||||
get => _highlightedProfile;
|
||||
set
|
||||
{
|
||||
_highlightedProfile = value;
|
||||
|
||||
OnPropertyChanged(nameof(HighlightedProfile));
|
||||
OnPropertyChanged(nameof(IsHighlightedProfileDeletable));
|
||||
OnPropertyChanged(nameof(IsHighlightedProfileEditable));
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
@ -78,64 +91,24 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public async void ChooseProfileImage()
|
||||
public void AddUser()
|
||||
{
|
||||
await SelectProfileImage();
|
||||
UserProfile userProfile = null;
|
||||
_owner.Navigate(typeof(UserEditor), (this._owner, userProfile, true));
|
||||
}
|
||||
|
||||
public async Task SelectProfileImage(bool isNewUser = false)
|
||||
public void EditUser()
|
||||
{
|
||||
ProfileImageSelectionDialog selectionDialog = new(_owner.ContentManager);
|
||||
|
||||
await selectionDialog.ShowDialog(_owner);
|
||||
|
||||
if (selectionDialog.BufferImageProfile != null)
|
||||
{
|
||||
if (isNewUser)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(_tempUserName))
|
||||
{
|
||||
_owner.AccountManager.AddUser(_tempUserName, selectionDialog.BufferImageProfile);
|
||||
}
|
||||
}
|
||||
else if (SelectedProfile != null)
|
||||
{
|
||||
_owner.AccountManager.SetUserImage(SelectedProfile.UserId, selectionDialog.BufferImageProfile);
|
||||
SelectedProfile.Image = selectionDialog.BufferImageProfile;
|
||||
|
||||
SelectedProfile = null;
|
||||
}
|
||||
|
||||
LoadProfiles();
|
||||
}
|
||||
}
|
||||
|
||||
public async void AddUser()
|
||||
{
|
||||
var dlgTitle = LocaleManager.Instance["InputDialogAddNewProfileTitle"];
|
||||
var dlgMainText = LocaleManager.Instance["InputDialogAddNewProfileHeader"];
|
||||
var dlgSubText = string.Format(LocaleManager.Instance["InputDialogAddNewProfileSubtext"],
|
||||
MaxProfileNameLength);
|
||||
|
||||
_tempUserName =
|
||||
await ContentDialogHelper.CreateInputDialog(dlgTitle, dlgMainText, dlgSubText, _owner,
|
||||
MaxProfileNameLength);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_tempUserName))
|
||||
{
|
||||
await SelectProfileImage(true);
|
||||
}
|
||||
|
||||
_tempUserName = String.Empty;
|
||||
_owner.Navigate(typeof(UserEditor), (this._owner, _highlightedProfile ?? SelectedProfile, false));
|
||||
}
|
||||
|
||||
public async void DeleteUser()
|
||||
{
|
||||
if (_selectedProfile != null)
|
||||
if (_highlightedProfile != null)
|
||||
{
|
||||
var lastUserId = _owner.AccountManager.LastOpenedUser.UserId;
|
||||
|
||||
if (_selectedProfile.UserId == lastUserId)
|
||||
if (_highlightedProfile.UserId == lastUserId)
|
||||
{
|
||||
// If we are deleting the currently open profile, then we must open something else before deleting.
|
||||
var profile = Profiles.FirstOrDefault(x => x.UserId != lastUserId);
|
||||
@ -144,8 +117,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
{
|
||||
Dispatcher.UIThread.Post(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(_owner,
|
||||
LocaleManager.Instance["DialogUserProfileDeletionWarningMessage"]);
|
||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogUserProfileDeletionWarningMessage"]);
|
||||
});
|
||||
|
||||
return;
|
||||
@ -155,13 +127,12 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
||||
}
|
||||
|
||||
var result =
|
||||
await ContentDialogHelper.CreateConfirmationDialog(_owner,
|
||||
LocaleManager.Instance["DialogUserProfileDeletionConfirmMessage"], "",
|
||||
await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance["DialogUserProfileDeletionConfirmMessage"], "",
|
||||
LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], "");
|
||||
|
||||
if (result == UserResult.Yes)
|
||||
{
|
||||
_owner.AccountManager.DeleteUser(_selectedProfile.UserId);
|
||||
_owner.AccountManager.DeleteUser(_highlightedProfile.UserId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
public class AboutWindow : StyleableWindow
|
||||
public partial class AboutWindow : StyleableWindow
|
||||
{
|
||||
public AboutWindow()
|
||||
{
|
||||
@ -39,15 +39,6 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
|
||||
public string Developers => string.Format(LocaleManager.Instance["AboutPageDeveloperListMore"], "gdkchan, Ac_K, Thog, rip in peri peri, LDj3SNuD, emmaus, Thealexbarney, Xpl0itR, GoffyDude, »jD«");
|
||||
|
||||
public TextBlock SupportersTextBlock { get; set; }
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
|
||||
SupportersTextBlock = this.FindControl<TextBlock>("SupportersTextBlock");
|
||||
}
|
||||
|
||||
private void Button_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button button)
|
||||
|
@ -7,7 +7,7 @@ using Ryujinx.Ava.Ui.ViewModels;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
public class AmiiboWindow : StyleableWindow
|
||||
public partial class AmiiboWindow : StyleableWindow
|
||||
{
|
||||
public AmiiboWindow(bool showAll, string lastScannedAmiiboId, string titleId)
|
||||
{
|
||||
@ -44,11 +44,6 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
public Amiibo.AmiiboApi ScannedAmiibo { get; set; }
|
||||
public AmiiboWindowViewModel ViewModel { get; set; }
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
private void ScanButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ViewModel.AmiiboSelectedIndex > -1)
|
||||
|
@ -1,36 +1,35 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
<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:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="350"
|
||||
x:Class="Ryujinx.Ava.Ui.Windows.AvatarWindow"
|
||||
CanResize="False"
|
||||
Margin="0"
|
||||
Padding="0"
|
||||
xmlns:Locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels"
|
||||
xmlns:controls="clr-namespace:Ryujinx.Ava.Ui.Controls"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
x:CompileBindings="True"
|
||||
x:DataType="viewModels:AvatarProfileViewModel"
|
||||
SizeToContent="WidthAndHeight">
|
||||
x:DataType="viewModels:AvatarProfileViewModel">
|
||||
<Design.DataContext>
|
||||
<viewModels:AvatarProfileViewModel />
|
||||
</Design.DataContext>
|
||||
<Window.Resources>
|
||||
<UserControl.Resources>
|
||||
<controls:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||
</Window.Resources>
|
||||
<Grid Margin="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ListBox Grid.Row="1" BorderThickness="0" SelectedIndex="{Binding SelectedIndex}" Width="600" Height="500"
|
||||
<ListBox Grid.Row="1" BorderThickness="0" SelectedIndex="{Binding SelectedIndex}" Height="400"
|
||||
Items="{Binding Images}" HorizontalAlignment="Stretch" VerticalAlignment="Center">
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel Orientation="Horizontal" MaxWidth="600" Margin="0" HorizontalAlignment="Center" />
|
||||
<WrapPanel Orientation="Horizontal" MaxWidth="700" Margin="0" HorizontalAlignment="Center" />
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
<ListBox.ItemTemplate>
|
||||
@ -45,9 +44,9 @@
|
||||
<StackPanel Grid.Row="3" Orientation="Horizontal" Spacing="10" Margin="10" HorizontalAlignment="Center">
|
||||
<Button Content="{Locale:Locale AvatarChoose}" Width="200" Name="ChooseButton" Click="ChooseButton_OnClick" />
|
||||
<ui:ColorPickerButton Color="{Binding BackgroundColor, Mode=TwoWay}" Name="ColorButton" />
|
||||
<Button HorizontalAlignment="Right" Content="{Locale:Locale AvatarClose}" Click="CloseButton_OnClick"
|
||||
<Button HorizontalAlignment="Right" Content="{Locale:Locale Discard}" Click="CloseButton_OnClick"
|
||||
Name="CloseButton"
|
||||
Width="200" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
</UserControl>
|
@ -1,70 +1,76 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using FluentAvalonia.UI.Navigation;
|
||||
using Ryujinx.Ava.Ui.Controls;
|
||||
using Ryujinx.Ava.Ui.Models;
|
||||
using Ryujinx.Ava.Ui.ViewModels;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
public class AvatarWindow : StyleableWindow
|
||||
public partial class AvatarWindow : UserControl
|
||||
{
|
||||
private NavigationDialogHost _parent;
|
||||
private TempProfile _profile;
|
||||
|
||||
public AvatarWindow(ContentManager contentManager)
|
||||
{
|
||||
ContentManager = contentManager;
|
||||
ViewModel = new AvatarProfileViewModel(() => ViewModel.ReloadImages());
|
||||
|
||||
DataContext = ViewModel;
|
||||
|
||||
InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["AvatarWindowTitle"];
|
||||
}
|
||||
|
||||
public AvatarWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
|
||||
AddHandler(Frame.NavigatedToEvent, (s, e) =>
|
||||
{
|
||||
NavigatedTo(e);
|
||||
}, RoutingStrategies.Direct);
|
||||
}
|
||||
|
||||
private void NavigatedTo(NavigationEventArgs arg)
|
||||
{
|
||||
if (Program.PreviewerDetached)
|
||||
{
|
||||
Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["AvatarWindowTitle"];
|
||||
if (arg.NavigationMode == NavigationMode.New)
|
||||
{
|
||||
(_parent, _profile) = ((NavigationDialogHost, TempProfile))arg.Parameter;
|
||||
ContentManager = _parent.ContentManager;
|
||||
if (Program.PreviewerDetached)
|
||||
{
|
||||
ViewModel = new AvatarProfileViewModel(() => ViewModel.ReloadImages());
|
||||
}
|
||||
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ContentManager ContentManager { get; }
|
||||
|
||||
public byte[] SelectedImage { get; set; }
|
||||
public ContentManager ContentManager { get; private set; }
|
||||
|
||||
internal AvatarProfileViewModel ViewModel { get; set; }
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
ViewModel.Dispose();
|
||||
base.OnClosed(e);
|
||||
}
|
||||
|
||||
private void CloseButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
ViewModel.Dispose();
|
||||
|
||||
_parent.GoBack();
|
||||
}
|
||||
|
||||
private void ChooseButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ViewModel.SelectedIndex > -1)
|
||||
{
|
||||
SelectedImage = ViewModel.SelectedImage;
|
||||
_profile.Image = ViewModel.SelectedImage;
|
||||
|
||||
Close();
|
||||
ViewModel.Dispose();
|
||||
|
||||
_parent.GoBack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ using System.Linq;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
public class CheatWindow : StyleableWindow
|
||||
public partial class CheatWindow : StyleableWindow
|
||||
{
|
||||
private readonly string _enabledCheatsPath;
|
||||
public bool NoCheatsFound { get; }
|
||||
@ -102,11 +102,6 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
this.AttachDevTools();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
if (NoCheatsFound)
|
||||
|
@ -24,11 +24,10 @@ using Key = Ryujinx.Input.Key;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
public class ControllerSettingsWindow : UserControl
|
||||
public partial class ControllerSettingsWindow : UserControl
|
||||
{
|
||||
private bool _dialogOpen;
|
||||
|
||||
public Grid SettingButtons { get; set; }
|
||||
private ButtonKeyAssigner _currentAssigner;
|
||||
internal ControllerSettingsViewModel ViewModel { get; set; }
|
||||
|
||||
@ -48,13 +47,6 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
|
||||
SettingButtons = this.FindControl<Grid>("SettingButtons");
|
||||
}
|
||||
|
||||
protected override void OnPointerReleased(PointerReleasedEventArgs e)
|
||||
{
|
||||
base.OnPointerReleased(e);
|
||||
@ -165,7 +157,6 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
_dialogOpen = true;
|
||||
|
||||
var result = await ContentDialogHelper.CreateConfirmationDialog(
|
||||
this.GetVisualRoot() as StyleableWindow,
|
||||
LocaleManager.Instance["DialogControllerSettingsModifiedConfirmMessage"],
|
||||
LocaleManager.Instance["DialogControllerSettingsModifiedConfirmSubMessage"],
|
||||
LocaleManager.Instance["InputDialogYes"],
|
||||
|
@ -1,7 +1,6 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Collections;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.Threading;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
@ -27,7 +26,7 @@ using Path = System.IO.Path;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
public class DlcManagerWindow : StyleableWindow
|
||||
public partial class DlcManagerWindow : StyleableWindow
|
||||
{
|
||||
private readonly List<DlcContainer> _dlcContainerList;
|
||||
private readonly string _dlcJsonPath;
|
||||
@ -35,7 +34,6 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
public VirtualFileSystem VirtualFileSystem { get; }
|
||||
|
||||
public AvaloniaList<DlcModel> Dlcs { get; set; }
|
||||
public Grid DlcGrid { get; private set; }
|
||||
public ulong TitleId { get; }
|
||||
public string TitleName { get; }
|
||||
|
||||
@ -84,15 +82,6 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
this.AttachDevTools();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
Dlcs = new AvaloniaList<DlcModel>();
|
||||
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
|
||||
DlcGrid = this.FindControl<Grid>("DlcGrid");
|
||||
}
|
||||
|
||||
private void LoadDlcs()
|
||||
{
|
||||
foreach (DlcContainer dlcContainer in _dlcContainerList)
|
||||
@ -129,8 +118,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(this,
|
||||
string.Format(LocaleManager.Instance[
|
||||
await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance[
|
||||
"DialogDlcLoadNcaErrorMessage"], ex.Message, containerPath));
|
||||
});
|
||||
}
|
||||
@ -180,7 +168,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
|
||||
if (!containsDlc)
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(this, LocaleManager.Instance["DialogDlcNoDlcErrorMessage"]);
|
||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogDlcNoDlcErrorMessage"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,18 +38,6 @@
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<controls:OffscreenTextBox Name="HiddenTextBox" Grid.Row="0" />
|
||||
<ContentControl
|
||||
Grid.Row="1"
|
||||
Focusable="False"
|
||||
IsVisible="False"
|
||||
KeyboardNavigation.IsTabStop="False">
|
||||
<ui:ContentDialog
|
||||
Name="ContentDialog"
|
||||
IsPrimaryButtonEnabled="True"
|
||||
IsSecondaryButtonEnabled="True"
|
||||
IsVisible="True"
|
||||
KeyboardNavigation.IsTabStop="False" />
|
||||
</ContentControl>
|
||||
<StackPanel Grid.Row="0" IsVisible="False">
|
||||
<controls:HotKeyControl Name="FullscreenHotKey" Command="{ReflectionBinding ToggleFullscreen}" />
|
||||
<controls:HotKeyControl Name="FullscreenHotKey2" Command="{ReflectionBinding ToggleFullscreen}" />
|
||||
@ -123,14 +111,20 @@
|
||||
Command="{ReflectionBinding ToggleFullscreen}"
|
||||
Header="{locale:Locale MenuBarOptionsToggleFullscreen}"
|
||||
InputGesture="F11" />
|
||||
<MenuItem Header="{locale:Locale MenuBarOptionsStartGamesInFullscreen}">
|
||||
<MenuItem>
|
||||
<MenuItem.Icon>
|
||||
<CheckBox IsChecked="{Binding StartGamesInFullscreen, Mode=TwoWay}" />
|
||||
<CheckBox IsChecked="{Binding StartGamesInFullscreen, Mode=TwoWay}"
|
||||
MinWidth="250">
|
||||
<TextBlock Text="{locale:Locale MenuBarOptionsStartGamesInFullscreen}"/>
|
||||
</CheckBox>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="{locale:Locale MenuBarOptionsShowConsole}" IsVisible="{Binding ShowConsoleVisible}">
|
||||
<MenuItem IsVisible="{Binding ShowConsoleVisible}">
|
||||
<MenuItem.Icon>
|
||||
<CheckBox IsChecked="{Binding ShowConsole, Mode=TwoWay}" />
|
||||
<CheckBox IsChecked="{Binding ShowConsole, Mode=TwoWay}"
|
||||
MinWidth="250">
|
||||
<TextBlock Text="{locale:Locale MenuBarOptionsShowConsole}"/>
|
||||
</CheckBox>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
@ -179,6 +173,10 @@
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="zh_CN"
|
||||
Header="Simplified Chinese" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="zh_TW"
|
||||
Header="Traditional Chinese (Taiwan)" />
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem
|
||||
|
@ -36,7 +36,7 @@ using InputManager = Ryujinx.Input.HLE.InputManager;
|
||||
using ProgressBar = Avalonia.Controls.ProgressBar;
|
||||
namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
public class MainWindow : StyleableWindow
|
||||
public partial class MainWindow : StyleableWindow
|
||||
{
|
||||
private bool _canUpdate;
|
||||
private bool _isClosing;
|
||||
@ -62,22 +62,6 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
public InputManager InputManager { get; private set; }
|
||||
|
||||
internal RendererControl GlRenderer { get; private set; }
|
||||
public ContentControl ContentFrame { get; private set; }
|
||||
public TextBlock LoadStatus { get; private set; }
|
||||
public TextBlock FirmwareStatus { get; private set; }
|
||||
public TextBox SearchBox { get; private set; }
|
||||
public ProgressBar LoadProgressBar { get; private set; }
|
||||
public Menu Menu { get; private set; }
|
||||
public MenuItem UpdateMenuItem { get; private set; }
|
||||
public MenuItem ActionsMenuItem { get; private set; }
|
||||
public GameGridView GameGrid { get; private set; }
|
||||
public GameListView GameList { get; private set; }
|
||||
public OffscreenTextBox HiddenTextBox { get; private set; }
|
||||
public HotKeyControl FullscreenHotKey { get; private set; }
|
||||
public HotKeyControl FullscreenHotKey2 { get; private set; }
|
||||
public HotKeyControl DockToggleHotKey { get; private set; }
|
||||
public HotKeyControl ExitHotKey { get; private set; }
|
||||
public ToggleSplitButton VolumeStatus { get; set; }
|
||||
internal MainWindowViewModel ViewModel { get; private set; }
|
||||
public SettingsWindow SettingsWindow { get; set; }
|
||||
|
||||
@ -102,6 +86,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
DataContext = ViewModel;
|
||||
|
||||
InitializeComponent();
|
||||
Load();
|
||||
AttachDebugDevTools();
|
||||
|
||||
UiHandler = new AvaHostUiHandler(this);
|
||||
@ -192,7 +177,9 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
string mainMessage = LocaleManager.Instance["DialogPerformanceCheckLoggingEnabledMessage"];
|
||||
string secondaryMessage = LocaleManager.Instance["DialogPerformanceCheckLoggingEnabledConfirmMessage"];
|
||||
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(this, mainMessage, secondaryMessage, LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], LocaleManager.Instance["RyujinxConfirm"]);
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(mainMessage, secondaryMessage,
|
||||
LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"],
|
||||
LocaleManager.Instance["RyujinxConfirm"]);
|
||||
|
||||
if (result != UserResult.Yes)
|
||||
{
|
||||
@ -205,9 +192,12 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
if (!string.IsNullOrWhiteSpace(ConfigurationState.Instance.Graphics.ShadersDumpPath.Value))
|
||||
{
|
||||
string mainMessage = LocaleManager.Instance["DialogPerformanceCheckShaderDumpEnabledMessage"];
|
||||
string secondaryMessage = LocaleManager.Instance["DialogPerformanceCheckShaderDumpEnabledConfirmMessage"];
|
||||
string secondaryMessage =
|
||||
LocaleManager.Instance["DialogPerformanceCheckShaderDumpEnabledConfirmMessage"];
|
||||
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(this, mainMessage, secondaryMessage, LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], LocaleManager.Instance["RyujinxConfirm"]);
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(mainMessage, secondaryMessage,
|
||||
LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"],
|
||||
LocaleManager.Instance["RyujinxConfirm"]);
|
||||
|
||||
if (result != UserResult.Yes)
|
||||
{
|
||||
@ -231,7 +221,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
if (AppHost != null)
|
||||
{
|
||||
await ContentDialogHelper.CreateInfoDialog(this,
|
||||
await ContentDialogHelper.CreateInfoDialog(
|
||||
LocaleManager.Instance["DialogLoadAppGameAlreadyLoadedMessage"],
|
||||
LocaleManager.Instance["DialogLoadAppGameAlreadyLoadedSubMessage"],
|
||||
LocaleManager.Instance["InputDialogOk"],
|
||||
@ -254,7 +244,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
|
||||
PrepareLoadScreen();
|
||||
|
||||
_mainViewContent = ContentFrame.Content as Control;
|
||||
_mainViewContent = Content.Content as Control;
|
||||
|
||||
GlRenderer = new RendererControl(3, 3, ConfigurationState.Instance.Logger.GraphicsDebugLevel);
|
||||
AppHost = new AppHost(GlRenderer, InputManager, path, VirtualFileSystem, ContentManager, AccountManager, _userChannelPersistence, this);
|
||||
@ -321,7 +311,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
|
||||
Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
ContentFrame.Content = GlRenderer;
|
||||
Content.Content = GlRenderer;
|
||||
|
||||
if (startFullscreen && WindowState != WindowState.FullScreen)
|
||||
{
|
||||
@ -365,9 +355,9 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
|
||||
Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
if (ContentFrame.Content != _mainViewContent)
|
||||
if (Content.Content != _mainViewContent)
|
||||
{
|
||||
ContentFrame.Content = _mainViewContent;
|
||||
Content.Content = _mainViewContent;
|
||||
}
|
||||
|
||||
ViewModel.ShowMenuAndStatusBar = true;
|
||||
@ -501,27 +491,8 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
ViewModel.IsAppletMenuActive = hasApplet;
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
private void Load()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
|
||||
ContentFrame = this.FindControl<ContentControl>("Content");
|
||||
GameList = this.FindControl<GameListView>("GameList");
|
||||
LoadStatus = this.FindControl<TextBlock>("LoadStatus");
|
||||
FirmwareStatus = this.FindControl<TextBlock>("FirmwareStatus");
|
||||
LoadProgressBar = this.FindControl<ProgressBar>("LoadProgressBar");
|
||||
SearchBox = this.FindControl<TextBox>("SearchBox");
|
||||
Menu = this.FindControl<Menu>("Menu");
|
||||
UpdateMenuItem = this.FindControl<MenuItem>("UpdateMenuItem");
|
||||
GameGrid = this.FindControl<GameGridView>("GameGrid");
|
||||
HiddenTextBox = this.FindControl<OffscreenTextBox>("HiddenTextBox");
|
||||
FullscreenHotKey = this.FindControl<HotKeyControl>("FullscreenHotKey");
|
||||
FullscreenHotKey2 = this.FindControl<HotKeyControl>("FullscreenHotKey2");
|
||||
DockToggleHotKey = this.FindControl<HotKeyControl>("DockToggleHotKey");
|
||||
ExitHotKey = this.FindControl<HotKeyControl>("ExitHotKey");
|
||||
VolumeStatus = this.FindControl<ToggleSplitButton>("VolumeStatus");
|
||||
ActionsMenuItem = this.FindControl<MenuItem>("ActionsMenuItem");
|
||||
|
||||
VolumeStatus.Click += VolumeStatus_CheckedChanged;
|
||||
|
||||
GameGrid.ApplicationOpened += Application_Opened;
|
||||
@ -710,7 +681,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
_isClosing = await ContentDialogHelper.CreateExitDialog(this);
|
||||
_isClosing = await ContentDialogHelper.CreateExitDialog();
|
||||
|
||||
if (_isClosing)
|
||||
{
|
||||
|
@ -9,13 +9,14 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
public class MotionSettingsWindow : UserControl
|
||||
public partial class MotionSettingsWindow : UserControl
|
||||
{
|
||||
private readonly InputConfiguration<GamepadInputId, StickInputId> _viewmodel;
|
||||
|
||||
public MotionSettingsWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = _viewmodel;
|
||||
}
|
||||
|
||||
public MotionSettingsWindow(ControllerSettingsViewModel viewmodel)
|
||||
@ -36,30 +37,21 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
};
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
DataContext = _viewmodel;
|
||||
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public static async Task Show(ControllerSettingsViewModel viewmodel, StyleableWindow window)
|
||||
public static async Task Show(ControllerSettingsViewModel viewmodel)
|
||||
{
|
||||
ContentDialog contentDialog = window.ContentDialog;
|
||||
|
||||
string name = string.Empty;
|
||||
|
||||
MotionSettingsWindow content = new MotionSettingsWindow(viewmodel);
|
||||
|
||||
if (contentDialog != null)
|
||||
ContentDialog contentDialog = new ContentDialog
|
||||
{
|
||||
contentDialog.Title = LocaleManager.Instance["ControllerMotionTitle"];
|
||||
contentDialog.PrimaryButtonText = LocaleManager.Instance["ControllerSettingsSave"];
|
||||
contentDialog.SecondaryButtonText = "";
|
||||
contentDialog.CloseButtonText = LocaleManager.Instance["ControllerSettingsClose"];
|
||||
contentDialog.Content = content;
|
||||
Title = LocaleManager.Instance["ControllerMotionTitle"],
|
||||
PrimaryButtonText = LocaleManager.Instance["ControllerSettingsSave"],
|
||||
SecondaryButtonText = "",
|
||||
CloseButtonText = LocaleManager.Instance["ControllerSettingsClose"],
|
||||
Content = content
|
||||
};
|
||||
contentDialog.PrimaryButtonClick += (sender, args) =>
|
||||
{
|
||||
var config = viewmodel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
|
||||
@ -77,5 +69,4 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
await contentDialog.ShowAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -9,13 +9,14 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
public class RumbleSettingsWindow : UserControl
|
||||
public partial class RumbleSettingsWindow : UserControl
|
||||
{
|
||||
private readonly InputConfiguration<GamepadInputId, StickInputId> _viewmodel;
|
||||
|
||||
public RumbleSettingsWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = _viewmodel;
|
||||
}
|
||||
|
||||
public RumbleSettingsWindow(ControllerSettingsViewModel viewmodel)
|
||||
@ -24,35 +25,26 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
|
||||
_viewmodel = new InputConfiguration<GamepadInputId, StickInputId>()
|
||||
{
|
||||
StrongRumble = config.StrongRumble,
|
||||
WeakRumble = config.WeakRumble
|
||||
StrongRumble = config.StrongRumble, WeakRumble = config.WeakRumble
|
||||
};
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
DataContext = _viewmodel;
|
||||
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public static async Task Show(ControllerSettingsViewModel viewmodel, StyleableWindow window)
|
||||
public static async Task Show(ControllerSettingsViewModel viewmodel)
|
||||
{
|
||||
ContentDialog contentDialog = window.ContentDialog;
|
||||
|
||||
string name = string.Empty;
|
||||
|
||||
RumbleSettingsWindow content = new RumbleSettingsWindow(viewmodel);
|
||||
|
||||
if (contentDialog != null)
|
||||
ContentDialog contentDialog = new ContentDialog
|
||||
{
|
||||
contentDialog.Title = LocaleManager.Instance["ControllerRumbleTitle"];
|
||||
contentDialog.PrimaryButtonText = LocaleManager.Instance["ControllerSettingsSave"];
|
||||
contentDialog.SecondaryButtonText = "";
|
||||
contentDialog.CloseButtonText = LocaleManager.Instance["ControllerSettingsClose"];
|
||||
contentDialog.Content = content;
|
||||
Title = LocaleManager.Instance["ControllerRumbleTitle"],
|
||||
PrimaryButtonText = LocaleManager.Instance["ControllerSettingsSave"],
|
||||
SecondaryButtonText = "",
|
||||
CloseButtonText = LocaleManager.Instance["ControllerSettingsClose"],
|
||||
Content = content,
|
||||
};
|
||||
|
||||
contentDialog.PrimaryButtonClick += (sender, args) =>
|
||||
{
|
||||
var config = viewmodel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
|
||||
@ -63,5 +55,4 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
await contentDialog.ShowAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -31,16 +31,11 @@
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ContentControl
|
||||
<ContentPresenter
|
||||
x:Name="ContentPresenter"
|
||||
Grid.Row="1"
|
||||
Focusable="False"
|
||||
IsVisible="False"
|
||||
KeyboardNavigation.IsTabStop="False">
|
||||
<ui:ContentDialog Name="ContentDialog"
|
||||
IsPrimaryButtonEnabled="True"
|
||||
IsSecondaryButtonEnabled="True"
|
||||
IsVisible="False" />
|
||||
</ContentControl>
|
||||
KeyboardNavigation.IsTabStop="False"/>
|
||||
<Grid Name="Pages" IsVisible="False" Grid.Row="2">
|
||||
<ScrollViewer Name="UiPage"
|
||||
Margin="0,0,10,0"
|
||||
@ -246,6 +241,22 @@
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysResScaleUpHotkey}" Width="230" />
|
||||
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
||||
<TextBlock
|
||||
Text="{Binding KeyboardHotkeys.ResScaleUp, Mode=TwoWay, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysResScaleDownHotkey}" Width="230" />
|
||||
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
||||
<TextBlock
|
||||
Text="{Binding KeyboardHotkeys.ResScaleDown, Mode=TwoWay, Converter={StaticResource Key}}"
|
||||
TextAlignment="Center" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</ScrollViewer>
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Presenters;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Data.Converters;
|
||||
@ -28,24 +29,8 @@ using TimeZone = Ryujinx.Ava.Ui.Models.TimeZone;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
public class SettingsWindow : StyleableWindow
|
||||
public partial class SettingsWindow : StyleableWindow
|
||||
{
|
||||
private ListBox _gameList;
|
||||
private TextBox _pathBox;
|
||||
private AutoCompleteBox _timeZoneBox;
|
||||
private ControllerSettingsWindow _controllerSettings;
|
||||
|
||||
// Pages
|
||||
private Control _uiPage;
|
||||
private Control _inputPage;
|
||||
private Control _hotkeysPage;
|
||||
private Control _systemPage;
|
||||
private Control _cpuPage;
|
||||
private Control _graphicsPage;
|
||||
private Control _audioPage;
|
||||
private Control _networkPage;
|
||||
private Control _loggingPage;
|
||||
private NavigationView _navPanel;
|
||||
private ButtonKeyAssigner _currentAssigner;
|
||||
|
||||
internal SettingsViewModel ViewModel { get; set; }
|
||||
@ -58,6 +43,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
DataContext = ViewModel;
|
||||
|
||||
InitializeComponent();
|
||||
Load();
|
||||
AttachDebugDevTools();
|
||||
|
||||
FuncMultiValueConverter<string, string> converter = new(parts => string.Format("{0} {1} {2}", parts.ToArray()));
|
||||
@ -66,7 +52,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
tzMultiBinding.Bindings.Add(new Binding("Location"));
|
||||
tzMultiBinding.Bindings.Add(new Binding("Abbreviation"));
|
||||
|
||||
_timeZoneBox.ValueMemberBinding = tzMultiBinding;
|
||||
TimeZoneBox.ValueMemberBinding = tzMultiBinding;
|
||||
}
|
||||
|
||||
public SettingsWindow()
|
||||
@ -75,6 +61,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
DataContext = ViewModel;
|
||||
|
||||
InitializeComponent();
|
||||
Load();
|
||||
AttachDebugDevTools();
|
||||
}
|
||||
|
||||
@ -84,31 +71,11 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
this.AttachDevTools();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
private void Load()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
|
||||
_pathBox = this.FindControl<TextBox>("PathBox");
|
||||
_gameList = this.FindControl<ListBox>("GameList");
|
||||
_timeZoneBox = this.FindControl<AutoCompleteBox>("TimeZoneBox");
|
||||
_controllerSettings = this.FindControl<ControllerSettingsWindow>("ControllerSettings");
|
||||
|
||||
_uiPage = this.FindControl<Control>("UiPage");
|
||||
_inputPage = this.FindControl<Control>("InputPage");
|
||||
_hotkeysPage = this.FindControl<Control>("HotkeysPage");
|
||||
_systemPage = this.FindControl<Control>("SystemPage");
|
||||
_cpuPage = this.FindControl<Control>("CpuPage");
|
||||
_graphicsPage = this.FindControl<Control>("GraphicsPage");
|
||||
_audioPage = this.FindControl<Control>("AudioPage");
|
||||
_networkPage = this.FindControl<Control>("NetworkPage");
|
||||
_loggingPage = this.FindControl<Control>("LoggingPage");
|
||||
|
||||
var pageGrid = this.FindControl<Grid>("Pages");
|
||||
pageGrid.Children.Clear();
|
||||
|
||||
_navPanel = this.FindControl<NavigationView>("NavPanel");
|
||||
_navPanel.SelectionChanged += NavPanelOnSelectionChanged;
|
||||
_navPanel.SelectedItem = _navPanel.MenuItems.ElementAt(0);
|
||||
Pages.Children.Clear();
|
||||
NavPanel.SelectionChanged += NavPanelOnSelectionChanged;
|
||||
NavPanel.SelectedItem = NavPanel.MenuItems.ElementAt(0);
|
||||
}
|
||||
|
||||
private void Button_Checked(object sender, RoutedEventArgs e)
|
||||
@ -174,31 +141,31 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
switch (navitem.Tag.ToString())
|
||||
{
|
||||
case "UiPage":
|
||||
_navPanel.Content = _uiPage;
|
||||
NavPanel.Content = UiPage;
|
||||
break;
|
||||
case "InputPage":
|
||||
_navPanel.Content = _inputPage;
|
||||
NavPanel.Content = InputPage;
|
||||
break;
|
||||
case "HotkeysPage":
|
||||
_navPanel.Content = _hotkeysPage;
|
||||
NavPanel.Content = HotkeysPage;
|
||||
break;
|
||||
case "SystemPage":
|
||||
_navPanel.Content = _systemPage;
|
||||
NavPanel.Content = SystemPage;
|
||||
break;
|
||||
case "CpuPage":
|
||||
_navPanel.Content = _cpuPage;
|
||||
NavPanel.Content = CpuPage;
|
||||
break;
|
||||
case "GraphicsPage":
|
||||
_navPanel.Content = _graphicsPage;
|
||||
NavPanel.Content = GraphicsPage;
|
||||
break;
|
||||
case "AudioPage":
|
||||
_navPanel.Content = _audioPage;
|
||||
NavPanel.Content = AudioPage;
|
||||
break;
|
||||
case "NetworkPage":
|
||||
_navPanel.Content = _networkPage;
|
||||
NavPanel.Content = NetworkPage;
|
||||
break;
|
||||
case "LoggingPage":
|
||||
_navPanel.Content = _loggingPage;
|
||||
NavPanel.Content = LoggingPage;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -206,7 +173,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
|
||||
private async void AddButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
string path = _pathBox.Text;
|
||||
string path = PathBox.Text;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(path) && Directory.Exists(path) && !ViewModel.GameDirectories.Contains(path))
|
||||
{
|
||||
@ -225,7 +192,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
|
||||
private void RemoveButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
List<string> selected = new(_gameList.SelectedItems.Cast<string>());
|
||||
List<string> selected = new(GameList.SelectedItems.Cast<string>());
|
||||
|
||||
foreach (string path in selected)
|
||||
{
|
||||
@ -279,7 +246,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
ViewModel.SaveSettings();
|
||||
|
||||
_controllerSettings?.SaveCurrentProfile();
|
||||
ControllerSettings?.SaveCurrentProfile();
|
||||
|
||||
if (Owner is MainWindow window)
|
||||
{
|
||||
@ -289,7 +256,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
_controllerSettings.Dispose();
|
||||
ControllerSettings.Dispose();
|
||||
_currentAssigner?.Cancel();
|
||||
_currentAssigner = null;
|
||||
base.OnClosed(e);
|
||||
|
@ -11,7 +11,6 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
public class StyleableWindow : Window
|
||||
{
|
||||
public ContentDialog ContentDialog { get; private set; }
|
||||
public IBitmap IconImage { get; set; }
|
||||
|
||||
public StyleableWindow()
|
||||
@ -26,15 +25,9 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
IconImage = new Bitmap(stream);
|
||||
}
|
||||
|
||||
public void LoadDialog()
|
||||
{
|
||||
ContentDialog = this.FindControl<ContentDialog>("ContentDialog");
|
||||
}
|
||||
|
||||
protected override void OnOpened(EventArgs e)
|
||||
{
|
||||
base.OnOpened(e);
|
||||
ContentDialog = this.FindControl<ContentDialog>("ContentDialog");
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
|
@ -28,14 +28,14 @@ using Avalonia.Threading;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
public class TitleUpdateWindow : StyleableWindow
|
||||
public partial class TitleUpdateWindow : StyleableWindow
|
||||
{
|
||||
private readonly string _updateJsonPath;
|
||||
private TitleUpdateMetadata _titleUpdateWindowData;
|
||||
|
||||
public VirtualFileSystem VirtualFileSystem { get; }
|
||||
|
||||
internal AvaloniaList<TitleUpdateModel> TitleUpdates { get; set; }
|
||||
internal AvaloniaList<TitleUpdateModel> TitleUpdates { get; set; } = new AvaloniaList<TitleUpdateModel>();
|
||||
public string TitleId { get; }
|
||||
public string TitleName { get; }
|
||||
|
||||
@ -84,13 +84,6 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
this.AttachDevTools();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
TitleUpdates = new AvaloniaList<TitleUpdateModel>();
|
||||
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
private void LoadUpdates()
|
||||
{
|
||||
TitleUpdates.Add(new TitleUpdateModel(default, string.Empty, true));
|
||||
@ -154,8 +147,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
Dispatcher.UIThread.Post(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(this,
|
||||
LocaleManager.Instance["DialogUpdateAddUpdateErrorMessage"]);
|
||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogUpdateAddUpdateErrorMessage"]);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -163,8 +155,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
Dispatcher.UIThread.Post(async () =>
|
||||
{
|
||||
await ContentDialogHelper.CreateErrorDialog(this,
|
||||
string.Format(LocaleManager.Instance["DialogDlcLoadNcaErrorMessage"], ex.Message, path));
|
||||
await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogDlcLoadNcaErrorMessage"], ex.Message, path));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
public class UpdaterWindow : StyleableWindow
|
||||
public partial class UpdaterWindow : StyleableWindow
|
||||
{
|
||||
private readonly string _buildUrl;
|
||||
private readonly MainWindow _mainWindow;
|
||||
@ -36,21 +36,6 @@ namespace Ryujinx.Ava.Ui.Windows
|
||||
_buildUrl = buildUrl;
|
||||
}
|
||||
|
||||
public TextBlock MainText { get; set; }
|
||||
public TextBlock SecondaryText { get; set; }
|
||||
public ProgressBar ProgressBar { get; set; }
|
||||
public StackPanel ButtonBox { get; set; }
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
|
||||
MainText = this.FindControl<TextBlock>("MainText");
|
||||
SecondaryText = this.FindControl<TextBlock>("SecondaryText");
|
||||
ProgressBar = this.FindControl<ProgressBar>("ProgressBar");
|
||||
ButtonBox = this.FindControl<StackPanel>("ButtonBox");
|
||||
}
|
||||
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
private static extern int chmod(string path, uint mode);
|
||||
|
||||
|
@ -1,107 +0,0 @@
|
||||
<window:StyleableWindow xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="350"
|
||||
x:Class="Ryujinx.Ava.Ui.Windows.UserProfileWindow"
|
||||
xmlns:Locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels"
|
||||
xmlns:controls="clr-namespace:Ryujinx.Ava.Ui.Controls"
|
||||
xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
|
||||
CanResize="False"
|
||||
Width="850" MinHeight="550" Height="550"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
SizeToContent="Manual"
|
||||
MinWidth="600">
|
||||
<Design.DataContext>
|
||||
<viewModels:UserProfileViewModel />
|
||||
</Design.DataContext>
|
||||
<Window.Resources>
|
||||
<controls:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||
</Window.Resources>
|
||||
<Grid Margin="15" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<ContentControl
|
||||
Focusable="False"
|
||||
IsVisible="False"
|
||||
KeyboardNavigation.IsTabStop="False">
|
||||
<ui:ContentDialog Name="ContentDialog"
|
||||
IsPrimaryButtonEnabled="True"
|
||||
IsSecondaryButtonEnabled="True"
|
||||
IsVisible="False" />
|
||||
</ContentControl>
|
||||
<TextBlock Text="{Locale:Locale UserProfilesSelectedUserProfile}" />
|
||||
<Grid Grid.Row="1" Margin="10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image Height="96" Width="96"
|
||||
Source="{Binding SelectedProfile.Image, Converter={StaticResource ByteImage}}" />
|
||||
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" Grid.Column="1" Spacing="10"
|
||||
Margin="5, 10">
|
||||
<TextBox Name="NameBox" Text="{Binding SelectedProfile.Name, Mode=OneWay}"
|
||||
HorizontalAlignment="Stretch" />
|
||||
<TextBlock Text="{Binding SelectedProfile.UserId}" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" Grid.Column="2" Spacing="10"
|
||||
Margin="5">
|
||||
<Button Content="{Locale:Locale UserProfilesSaveProfileName}" Name="SetNameButton"
|
||||
Click="SetNameButton_OnClick" />
|
||||
<Button Name="SelectProfileImage" Command="{Binding ChooseProfileImage}"
|
||||
Content="{Locale:Locale UserProfilesChangeProfileImage}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid Grid.Row="2">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Text="{Locale:Locale UserProfilesAvailableUserProfiles}" />
|
||||
<ListBox Grid.Row="1" Margin="10" Name="ProfilesList" DoubleTapped="ProfilesList_DoubleTapped"
|
||||
Items="{Binding Profiles}">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid HorizontalAlignment="Stretch">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Column="0" Background="{DynamicResource ThemeAccentColorBrush}"
|
||||
Grid.ColumnSpan="2"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinHeight="5" MinWidth="5"
|
||||
IsVisible="{Binding IsOpened}" />
|
||||
<Image Grid.Column="0" Height="96" Width="96"
|
||||
Source="{Binding Image, Converter={StaticResource ByteImage}}" />
|
||||
<StackPanel Margin="10" Orientation="Vertical" HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center" Grid.Column="1">
|
||||
<TextBlock Text="{Binding Name}" />
|
||||
<TextBlock Text="{Binding UserId}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Grid>
|
||||
<StackPanel Grid.Row="3" Orientation="Horizontal" Margin="10,0" Spacing="10" HorizontalAlignment="Stretch">
|
||||
<Button Content="{Locale:Locale UserProfilesAddNewProfile}" Command="{Binding AddUser}" />
|
||||
<Button IsEnabled="{Binding IsSelectedProfileDeletable}"
|
||||
Content="{Locale:Locale UserProfilesDeleteSelectedProfile}" Command="{Binding DeleteUser}" />
|
||||
<Button HorizontalAlignment="Right" Content="{Locale:Locale UserProfilesClose}" Click="CloseButton_OnClick"
|
||||
Name="CloseButton" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</window:StyleableWindow>
|
@ -1,102 +0,0 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Ui.ViewModels;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||
using System.Threading.Tasks;
|
||||
using UserProfile = Ryujinx.Ava.Ui.Models.UserProfile;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Windows
|
||||
{
|
||||
public class UserProfileWindow : StyleableWindow
|
||||
{
|
||||
private TextBox _nameBox;
|
||||
|
||||
public UserProfileWindow(AccountManager accountManager, ContentManager contentManager,
|
||||
VirtualFileSystem virtualFileSystem)
|
||||
{
|
||||
AccountManager = accountManager;
|
||||
ContentManager = contentManager;
|
||||
ViewModel = new UserProfileViewModel(this);
|
||||
|
||||
DataContext = ViewModel;
|
||||
|
||||
InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
if (contentManager.GetCurrentFirmwareVersion() != null)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
AvatarProfileViewModel.PreloadAvatars(contentManager, virtualFileSystem);
|
||||
});
|
||||
}
|
||||
|
||||
Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["UserProfileWindowTitle"];
|
||||
}
|
||||
|
||||
public UserProfileWindow()
|
||||
{
|
||||
ViewModel = new UserProfileViewModel();
|
||||
|
||||
DataContext = ViewModel;
|
||||
|
||||
InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["UserProfileWindowTitle"];
|
||||
}
|
||||
|
||||
public AccountManager AccountManager { get; }
|
||||
public ContentManager ContentManager { get; }
|
||||
|
||||
public UserProfileViewModel ViewModel { get; set; }
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
_nameBox = this.FindControl<TextBox>("NameBox");
|
||||
}
|
||||
|
||||
private void ProfilesList_DoubleTapped(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is ListBox listBox)
|
||||
{
|
||||
int selectedIndex = listBox.SelectedIndex;
|
||||
|
||||
if (selectedIndex >= 0 && selectedIndex < ViewModel.Profiles.Count)
|
||||
{
|
||||
ViewModel.SelectedProfile = ViewModel.Profiles[selectedIndex];
|
||||
|
||||
AccountManager.OpenUser(ViewModel.SelectedProfile.UserId);
|
||||
|
||||
ViewModel.LoadProfiles();
|
||||
|
||||
foreach (UserProfile profile in ViewModel.Profiles)
|
||||
{
|
||||
profile.UpdateState();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void SetNameButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(_nameBox.Text))
|
||||
{
|
||||
ViewModel.SelectedProfile.Name = _nameBox.Text;
|
||||
AccountManager.SetUserName(ViewModel.SelectedProfile.UserId, _nameBox.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,5 +7,7 @@
|
||||
public Key ShowUi { get; set; }
|
||||
public Key Pause { get; set; }
|
||||
public Key ToggleMute { get; set; }
|
||||
public Key ResScaleUp { get; set; }
|
||||
public Key ResScaleDown { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
||||
private const ushort FileFormatVersionMajor = 1;
|
||||
private const ushort FileFormatVersionMinor = 1;
|
||||
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
||||
private const uint CodeGenVersion = 3472;
|
||||
private const uint CodeGenVersion = 3469;
|
||||
|
||||
private const string SharedTocFileName = "shared.toc";
|
||||
private const string SharedDataFileName = "shared.data";
|
||||
|
@ -45,7 +45,7 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||
{
|
||||
(int minVersion, int maxVersion) = value;
|
||||
|
||||
for (int version = minVersion; version <= maxVersion; version++)
|
||||
for (int version = maxVersion; version >= minVersion; version--)
|
||||
{
|
||||
if (NativeLibrary.TryLoad(FormatLibraryNameForCurrentOs(libraryName, version), assembly, searchPath, out handle))
|
||||
{
|
||||
|
@ -104,12 +104,23 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Figure out how this is supposed to work in the
|
||||
// presence of other condition codes.
|
||||
if (op.Ccc == Ccc.T)
|
||||
{
|
||||
context.Return();
|
||||
}
|
||||
else
|
||||
{
|
||||
Operand cond = GetCondition(context, op.Ccc, IrConsts.False);
|
||||
|
||||
// If the condition is always false, we don't need to do anything.
|
||||
if (cond.Type != OperandType.Constant || cond.Value != IrConsts.False)
|
||||
{
|
||||
Operand lblSkip = Label();
|
||||
context.BranchIfFalse(lblSkip, cond);
|
||||
context.Return();
|
||||
context.MarkLabel(lblSkip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Kil(EmitterContext context)
|
||||
@ -250,7 +261,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||
}
|
||||
}
|
||||
|
||||
private static Operand GetCondition(EmitterContext context, Ccc cond)
|
||||
private static Operand GetCondition(EmitterContext context, Ccc cond, int defaultCond = IrConsts.True)
|
||||
{
|
||||
// TODO: More condition codes, figure out how they work.
|
||||
switch (cond)
|
||||
@ -263,7 +274,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||
return context.BitwiseNot(GetZF());
|
||||
}
|
||||
|
||||
return Const(IrConsts.True);
|
||||
return Const(defaultCond);
|
||||
}
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ namespace Ryujinx.Ui.Common.Configuration
|
||||
/// <summary>
|
||||
/// The current version of the file format
|
||||
/// </summary>
|
||||
public const int CurrentVersion = 38;
|
||||
public const int CurrentVersion = 39;
|
||||
|
||||
/// <summary>
|
||||
/// Version of the configuration file format
|
||||
|
@ -648,7 +648,9 @@ namespace Ryujinx.Ui.Common.Configuration
|
||||
ToggleMute = Key.F2,
|
||||
Screenshot = Key.F8,
|
||||
ShowUi = Key.F4,
|
||||
Pause = Key.F5
|
||||
Pause = Key.F5,
|
||||
ResScaleUp = Key.Unbound,
|
||||
ResScaleDown = Key.Unbound
|
||||
};
|
||||
Hid.InputConfig.Value = new List<InputConfig>
|
||||
{
|
||||
@ -1096,6 +1098,22 @@ namespace Ryujinx.Ui.Common.Configuration
|
||||
configurationFileUpdated = true;
|
||||
}
|
||||
|
||||
if (configurationFileFormat.Version < 39)
|
||||
{
|
||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 39.");
|
||||
|
||||
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||
{
|
||||
ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
|
||||
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
||||
ShowUi = configurationFileFormat.Hotkeys.ShowUi,
|
||||
Pause = configurationFileFormat.Hotkeys.Pause,
|
||||
ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
|
||||
ResScaleUp = Key.Unbound,
|
||||
ResScaleDown = Key.Unbound
|
||||
};
|
||||
}
|
||||
|
||||
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
|
||||
Graphics.ResScale.Value = configurationFileFormat.ResScale;
|
||||
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
|
||||
|
@ -6,6 +6,7 @@ using Ryujinx.Common;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Ui.Common.Configuration;
|
||||
using Ryujinx.Graphics.Gpu;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.GAL.Multithreading;
|
||||
using Ryujinx.Input;
|
||||
@ -33,6 +34,7 @@ namespace Ryujinx.Ui
|
||||
private const int SwitchPanelWidth = 1280;
|
||||
private const int SwitchPanelHeight = 720;
|
||||
private const int TargetFps = 60;
|
||||
private const float MaxResolutionScale = 4.0f; // Max resolution hotkeys can scale to before wrapping.
|
||||
|
||||
public ManualResetEvent WaitEvent { get; set; }
|
||||
public NpadManager NpadManager { get; }
|
||||
@ -618,6 +620,19 @@ namespace Ryujinx.Ui
|
||||
}
|
||||
}
|
||||
|
||||
if (currentHotkeyState.HasFlag(KeyboardHotkeyState.ResScaleUp) &&
|
||||
!_prevHotkeyState.HasFlag(KeyboardHotkeyState.ResScaleUp))
|
||||
{
|
||||
GraphicsConfig.ResScale = GraphicsConfig.ResScale % MaxResolutionScale + 1;
|
||||
}
|
||||
|
||||
if (currentHotkeyState.HasFlag(KeyboardHotkeyState.ResScaleDown) &&
|
||||
!_prevHotkeyState.HasFlag(KeyboardHotkeyState.ResScaleDown))
|
||||
{
|
||||
GraphicsConfig.ResScale =
|
||||
(MaxResolutionScale + GraphicsConfig.ResScale - 2) % MaxResolutionScale + 1;
|
||||
}
|
||||
|
||||
_prevHotkeyState = currentHotkeyState;
|
||||
}
|
||||
|
||||
@ -648,7 +663,9 @@ namespace Ryujinx.Ui
|
||||
Screenshot = 1 << 1,
|
||||
ShowUi = 1 << 2,
|
||||
Pause = 1 << 3,
|
||||
ToggleMute = 1 << 4
|
||||
ToggleMute = 1 << 4,
|
||||
ResScaleUp = 1 << 5,
|
||||
ResScaleDown = 1 << 6
|
||||
}
|
||||
|
||||
private KeyboardHotkeyState GetHotkeyState()
|
||||
@ -680,6 +697,16 @@ namespace Ryujinx.Ui
|
||||
state |= KeyboardHotkeyState.ToggleMute;
|
||||
}
|
||||
|
||||
if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ResScaleUp))
|
||||
{
|
||||
state |= KeyboardHotkeyState.ResScaleUp;
|
||||
}
|
||||
|
||||
if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ResScaleDown))
|
||||
{
|
||||
state |= KeyboardHotkeyState.ResScaleDown;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user