MainMenuBarView.axaml.cs
1 using Avalonia; 2 using Avalonia.Controls; 3 using Avalonia.Interactivity; 4 using Avalonia.Threading; 5 using LibHac.Ncm; 6 using LibHac.Tools.FsSystem.NcaUtils; 7 using Ryujinx.Ava.Common.Locale; 8 using Ryujinx.Ava.UI.Helpers; 9 using Ryujinx.Ava.UI.ViewModels; 10 using Ryujinx.Ava.UI.Windows; 11 using Ryujinx.Common; 12 using Ryujinx.Common.Utilities; 13 using Ryujinx.Modules; 14 using Ryujinx.UI.App.Common; 15 using Ryujinx.UI.Common; 16 using Ryujinx.UI.Common.Configuration; 17 using Ryujinx.UI.Common.Helper; 18 using System; 19 using System.Collections.Generic; 20 using System.IO; 21 using System.Linq; 22 23 namespace Ryujinx.Ava.UI.Views.Main 24 { 25 public partial class MainMenuBarView : UserControl 26 { 27 public MainWindow Window { get; private set; } 28 public MainWindowViewModel ViewModel { get; private set; } 29 30 public MainMenuBarView() 31 { 32 InitializeComponent(); 33 34 ToggleFileTypesMenuItem.ItemsSource = GenerateToggleFileTypeItems(); 35 ChangeLanguageMenuItem.ItemsSource = GenerateLanguageMenuItems(); 36 } 37 38 private CheckBox[] GenerateToggleFileTypeItems() 39 { 40 List<CheckBox> checkBoxes = new(); 41 42 foreach (var item in Enum.GetValues(typeof(FileTypes))) 43 { 44 string fileName = Enum.GetName(typeof(FileTypes), item); 45 checkBoxes.Add(new CheckBox 46 { 47 Content = $".{fileName}", 48 IsChecked = ((FileTypes)item).GetConfigValue(ConfigurationState.Instance.UI.ShownFileTypes), 49 Command = MiniCommand.Create(() => Window.ToggleFileType(fileName)), 50 }); 51 } 52 53 return checkBoxes.ToArray(); 54 } 55 56 private static MenuItem[] GenerateLanguageMenuItems() 57 { 58 List<MenuItem> menuItems = new(); 59 60 string localePath = "Ryujinx/Assets/Locales"; 61 string localeExt = ".json"; 62 63 string[] localesPath = EmbeddedResources.GetAllAvailableResources(localePath, localeExt); 64 65 Array.Sort(localesPath); 66 67 foreach (string locale in localesPath) 68 { 69 string languageCode = Path.GetFileNameWithoutExtension(locale).Split('.').Last(); 70 string languageJson = EmbeddedResources.ReadAllText($"{localePath}/{languageCode}{localeExt}"); 71 var strings = JsonHelper.Deserialize(languageJson, CommonJsonContext.Default.StringDictionary); 72 73 if (!strings.TryGetValue("Language", out string languageName)) 74 { 75 languageName = languageCode; 76 } 77 78 MenuItem menuItem = new() 79 { 80 Header = languageName, 81 Command = MiniCommand.Create(() => 82 { 83 MainWindowViewModel.ChangeLanguage(languageCode); 84 }), 85 }; 86 87 menuItems.Add(menuItem); 88 } 89 90 return menuItems.ToArray(); 91 } 92 93 protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) 94 { 95 base.OnAttachedToVisualTree(e); 96 97 if (VisualRoot is MainWindow window) 98 { 99 Window = window; 100 } 101 102 ViewModel = Window.ViewModel; 103 DataContext = ViewModel; 104 } 105 106 private async void StopEmulation_Click(object sender, RoutedEventArgs e) 107 { 108 await Window.ViewModel.AppHost?.ShowExitPrompt(); 109 } 110 111 private void PauseEmulation_Click(object sender, RoutedEventArgs e) 112 { 113 Window.ViewModel.AppHost?.Pause(); 114 } 115 116 private void ResumeEmulation_Click(object sender, RoutedEventArgs e) 117 { 118 Window.ViewModel.AppHost?.Resume(); 119 } 120 121 public async void OpenSettings(object sender, RoutedEventArgs e) 122 { 123 Window.SettingsWindow = new(Window.VirtualFileSystem, Window.ContentManager); 124 125 await Window.SettingsWindow.ShowDialog(Window); 126 127 Window.SettingsWindow = null; 128 129 ViewModel.LoadConfigurableHotKeys(); 130 } 131 132 public async void OpenMiiApplet(object sender, RoutedEventArgs e) 133 { 134 string contentPath = ViewModel.ContentManager.GetInstalledContentPath(0x0100000000001009, StorageId.BuiltInSystem, NcaContentType.Program); 135 136 if (!string.IsNullOrEmpty(contentPath)) 137 { 138 ApplicationData applicationData = new() 139 { 140 Name = "miiEdit", 141 Id = 0x0100000000001009, 142 Path = contentPath, 143 }; 144 145 await ViewModel.LoadApplication(applicationData, ViewModel.IsFullScreen || ViewModel.StartGamesInFullscreen); 146 } 147 } 148 149 public async void OpenAmiiboWindow(object sender, RoutedEventArgs e) 150 { 151 if (!ViewModel.IsAmiiboRequested) 152 { 153 return; 154 } 155 156 if (ViewModel.AppHost.Device.System.SearchingForAmiibo(out int deviceId)) 157 { 158 string titleId = ViewModel.AppHost.Device.Processes.ActiveApplication.ProgramIdText.ToUpper(); 159 AmiiboWindow window = new(ViewModel.ShowAll, ViewModel.LastScannedAmiiboId, titleId); 160 161 await window.ShowDialog(Window); 162 163 if (window.IsScanned) 164 { 165 ViewModel.ShowAll = window.ViewModel.ShowAllAmiibo; 166 ViewModel.LastScannedAmiiboId = window.ScannedAmiibo.GetId(); 167 168 ViewModel.AppHost.Device.System.ScanAmiibo(deviceId, ViewModel.LastScannedAmiiboId, window.ViewModel.UseRandomUuid); 169 } 170 } 171 } 172 173 public async void OpenCheatManagerForCurrentApp(object sender, RoutedEventArgs e) 174 { 175 if (!ViewModel.IsGameRunning) 176 { 177 return; 178 } 179 180 string name = ViewModel.AppHost.Device.Processes.ActiveApplication.ApplicationControlProperties.Title[(int)ViewModel.AppHost.Device.System.State.DesiredTitleLanguage].NameString.ToString(); 181 182 await new CheatWindow( 183 Window.VirtualFileSystem, 184 ViewModel.AppHost.Device.Processes.ActiveApplication.ProgramIdText, 185 name, 186 Window.ViewModel.SelectedApplication.Path).ShowDialog(Window); 187 188 ViewModel.AppHost.Device.EnableCheats(); 189 } 190 191 private void ScanAmiiboMenuItem_AttachedToVisualTree(object sender, VisualTreeAttachmentEventArgs e) 192 { 193 if (sender is MenuItem) 194 { 195 ViewModel.IsAmiiboRequested = Window.ViewModel.AppHost.Device.System.SearchingForAmiibo(out _); 196 } 197 } 198 199 private async void InstallFileTypes_Click(object sender, RoutedEventArgs e) 200 { 201 if (FileAssociationHelper.Install()) 202 { 203 await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogInstallFileTypesSuccessMessage], string.Empty, LocaleManager.Instance[LocaleKeys.InputDialogOk], string.Empty, string.Empty); 204 } 205 else 206 { 207 await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogInstallFileTypesErrorMessage]); 208 } 209 } 210 211 private async void UninstallFileTypes_Click(object sender, RoutedEventArgs e) 212 { 213 if (FileAssociationHelper.Uninstall()) 214 { 215 await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogUninstallFileTypesSuccessMessage], string.Empty, LocaleManager.Instance[LocaleKeys.InputDialogOk], string.Empty, string.Empty); 216 } 217 else 218 { 219 await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUninstallFileTypesErrorMessage]); 220 } 221 } 222 223 private async void ChangeWindowSize_Click(object sender, RoutedEventArgs e) 224 { 225 if (sender is MenuItem item) 226 { 227 int height; 228 int width; 229 230 switch (item.Tag) 231 { 232 case "720": 233 height = 720; 234 width = 1280; 235 break; 236 237 case "1080": 238 height = 1080; 239 width = 1920; 240 break; 241 242 default: 243 throw new ArgumentNullException($"Invalid Tag for {item}"); 244 } 245 246 await Dispatcher.UIThread.InvokeAsync(() => 247 { 248 ViewModel.WindowState = WindowState.Normal; 249 250 height += (int)Window.StatusBarHeight + (int)Window.MenuBarHeight; 251 252 Window.Arrange(new Rect(Window.Position.X, Window.Position.Y, width, height)); 253 }); 254 } 255 } 256 257 public async void CheckForUpdates(object sender, RoutedEventArgs e) 258 { 259 if (Updater.CanUpdate(true)) 260 { 261 await Updater.BeginParse(Window, true); 262 } 263 } 264 265 public async void OpenAboutWindow(object sender, RoutedEventArgs e) 266 { 267 await AboutWindow.Show(); 268 } 269 270 public void CloseWindow(object sender, RoutedEventArgs e) 271 { 272 Window.Close(); 273 } 274 } 275 }