SettingsWindow.axaml.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. using Avalonia.Controls;
  2. using Avalonia.Controls.Primitives;
  3. using Avalonia.Data;
  4. using Avalonia.Data.Converters;
  5. using Avalonia.Input;
  6. using Avalonia.Interactivity;
  7. using FluentAvalonia.Core;
  8. using FluentAvalonia.UI.Controls;
  9. using Ryujinx.Ava.Common.Locale;
  10. using Ryujinx.Ava.Ui.Controls;
  11. using Ryujinx.Ava.Ui.ViewModels;
  12. using Ryujinx.HLE.FileSystem;
  13. using Ryujinx.Input;
  14. using Ryujinx.Input.Assigner;
  15. using System;
  16. using System.Collections.Generic;
  17. using System.IO;
  18. using System.Linq;
  19. using System.Threading.Tasks;
  20. using TimeZone = Ryujinx.Ava.Ui.Models.TimeZone;
  21. namespace Ryujinx.Ava.Ui.Windows
  22. {
  23. public partial class SettingsWindow : StyleableWindow
  24. {
  25. private ButtonKeyAssigner _currentAssigner;
  26. internal SettingsViewModel ViewModel { get; set; }
  27. public SettingsWindow(VirtualFileSystem virtualFileSystem, ContentManager contentManager)
  28. {
  29. Title = $"Ryujinx {Program.Version} - {LocaleManager.Instance["Settings"]}";
  30. ViewModel = new SettingsViewModel(virtualFileSystem, contentManager, this);
  31. DataContext = ViewModel;
  32. InitializeComponent();
  33. Load();
  34. FuncMultiValueConverter<string, string> converter = new(parts => string.Format("{0} {1} {2}", parts.ToArray()));
  35. MultiBinding tzMultiBinding = new() { Converter = converter };
  36. tzMultiBinding.Bindings.Add(new Binding("UtcDifference"));
  37. tzMultiBinding.Bindings.Add(new Binding("Location"));
  38. tzMultiBinding.Bindings.Add(new Binding("Abbreviation"));
  39. TimeZoneBox.ValueMemberBinding = tzMultiBinding;
  40. }
  41. public SettingsWindow()
  42. {
  43. ViewModel = new SettingsViewModel();
  44. DataContext = ViewModel;
  45. InitializeComponent();
  46. Load();
  47. }
  48. private void Load()
  49. {
  50. Pages.Children.Clear();
  51. NavPanel.SelectionChanged += NavPanelOnSelectionChanged;
  52. NavPanel.SelectedItem = NavPanel.MenuItems.ElementAt(0);
  53. }
  54. private void Button_Checked(object sender, RoutedEventArgs e)
  55. {
  56. if (sender is ToggleButton button)
  57. {
  58. if (_currentAssigner != null && button == _currentAssigner.ToggledButton)
  59. {
  60. return;
  61. }
  62. if (_currentAssigner == null && (bool)button.IsChecked)
  63. {
  64. _currentAssigner = new ButtonKeyAssigner(button);
  65. FocusManager.Instance.Focus(this, NavigationMethod.Pointer);
  66. PointerPressed += MouseClick;
  67. IKeyboard keyboard = (IKeyboard)ViewModel.AvaloniaKeyboardDriver.GetGamepad(ViewModel.AvaloniaKeyboardDriver.GamepadsIds[0]);
  68. IButtonAssigner assigner = new KeyboardKeyAssigner(keyboard);
  69. _currentAssigner.GetInputAndAssign(assigner);
  70. }
  71. else
  72. {
  73. if (_currentAssigner != null)
  74. {
  75. ToggleButton oldButton = _currentAssigner.ToggledButton;
  76. _currentAssigner.Cancel();
  77. _currentAssigner = null;
  78. button.IsChecked = false;
  79. }
  80. }
  81. }
  82. }
  83. private void Button_Unchecked(object sender, RoutedEventArgs e)
  84. {
  85. _currentAssigner?.Cancel();
  86. _currentAssigner = null;
  87. }
  88. private void MouseClick(object sender, PointerPressedEventArgs e)
  89. {
  90. bool shouldUnbind = false;
  91. if (e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed)
  92. {
  93. shouldUnbind = true;
  94. }
  95. _currentAssigner?.Cancel(shouldUnbind);
  96. PointerPressed -= MouseClick;
  97. }
  98. private void NavPanelOnSelectionChanged(object sender, NavigationViewSelectionChangedEventArgs e)
  99. {
  100. if (e.SelectedItem is NavigationViewItem navitem)
  101. {
  102. switch (navitem.Tag.ToString())
  103. {
  104. case "UiPage":
  105. NavPanel.Content = UiPage;
  106. break;
  107. case "InputPage":
  108. NavPanel.Content = InputPage;
  109. break;
  110. case "HotkeysPage":
  111. NavPanel.Content = HotkeysPage;
  112. break;
  113. case "SystemPage":
  114. NavPanel.Content = SystemPage;
  115. break;
  116. case "CpuPage":
  117. NavPanel.Content = CpuPage;
  118. break;
  119. case "GraphicsPage":
  120. NavPanel.Content = GraphicsPage;
  121. break;
  122. case "AudioPage":
  123. NavPanel.Content = AudioPage;
  124. break;
  125. case "NetworkPage":
  126. NavPanel.Content = NetworkPage;
  127. break;
  128. case "LoggingPage":
  129. NavPanel.Content = LoggingPage;
  130. break;
  131. }
  132. }
  133. }
  134. private async void AddButton_OnClick(object sender, RoutedEventArgs e)
  135. {
  136. string path = PathBox.Text;
  137. if (!string.IsNullOrWhiteSpace(path) && Directory.Exists(path) && !ViewModel.GameDirectories.Contains(path))
  138. {
  139. ViewModel.GameDirectories.Add(path);
  140. ViewModel.DirectoryChanged = true;
  141. }
  142. else
  143. {
  144. path = await new OpenFolderDialog().ShowAsync(this);
  145. if (!string.IsNullOrWhiteSpace(path))
  146. {
  147. ViewModel.GameDirectories.Add(path);
  148. ViewModel.DirectoryChanged = true;
  149. }
  150. }
  151. }
  152. private void RemoveButton_OnClick(object sender, RoutedEventArgs e)
  153. {
  154. List<string> selected = new(GameList.SelectedItems.Cast<string>());
  155. foreach (string path in selected)
  156. {
  157. ViewModel.GameDirectories.Remove(path);
  158. ViewModel.DirectoryChanged = true;
  159. }
  160. }
  161. private void TimeZoneBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
  162. {
  163. if (e.AddedItems != null && e.AddedItems.Count > 0)
  164. {
  165. if (e.AddedItems[0] is TimeZone timeZone)
  166. {
  167. e.Handled = true;
  168. ViewModel.ValidateAndSetTimeZone(timeZone.Location);
  169. }
  170. }
  171. }
  172. private void TimeZoneBox_OnTextChanged(object sender, EventArgs e)
  173. {
  174. if (sender is AutoCompleteBox box)
  175. {
  176. if (box.SelectedItem != null && box.SelectedItem is TimeZone timeZone)
  177. {
  178. ViewModel.ValidateAndSetTimeZone(timeZone.Location);
  179. }
  180. }
  181. }
  182. private async void SaveButton_Clicked(object sender, RoutedEventArgs e)
  183. {
  184. await SaveSettings();
  185. Close();
  186. }
  187. private void CloseButton_Clicked(object sender, RoutedEventArgs e)
  188. {
  189. ViewModel.RevertIfNotSaved();
  190. Close();
  191. }
  192. private async void ApplyButton_Clicked(object sender, RoutedEventArgs e)
  193. {
  194. await SaveSettings();
  195. }
  196. private async Task SaveSettings()
  197. {
  198. await ViewModel.SaveSettings();
  199. ControllerSettings?.SaveCurrentProfile();
  200. if (Owner is MainWindow window && ViewModel.DirectoryChanged)
  201. {
  202. window.ViewModel.LoadApplications();
  203. }
  204. ViewModel.DirectoryChanged = false;
  205. }
  206. protected override void OnClosed(EventArgs e)
  207. {
  208. ControllerSettings.Dispose();
  209. _currentAssigner?.Cancel();
  210. _currentAssigner = null;
  211. base.OnClosed(e);
  212. }
  213. }
  214. }