SettingsWindow.axaml.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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.Helpers;
  12. using Ryujinx.Ava.UI.ViewModels;
  13. using Ryujinx.HLE.FileSystem;
  14. using Ryujinx.Input;
  15. using Ryujinx.Input.Assigner;
  16. using System;
  17. using System.Collections.Generic;
  18. using System.IO;
  19. using System.Linq;
  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[LocaleKeys.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()).Trim());
  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. NavPanel.Content = navitem.Tag.ToString() switch
  103. {
  104. "UiPage" => UiPage,
  105. "InputPage" => InputPage,
  106. "HotkeysPage" => HotkeysPage,
  107. "SystemPage" => SystemPage,
  108. "CpuPage" => CpuPage,
  109. "GraphicsPage" => GraphicsPage,
  110. "AudioPage" => AudioPage,
  111. "NetworkPage" => NetworkPage,
  112. "LoggingPage" => LoggingPage,
  113. _ => throw new NotImplementedException()
  114. };
  115. }
  116. }
  117. private async void AddButton_OnClick(object sender, RoutedEventArgs e)
  118. {
  119. string path = PathBox.Text;
  120. if (!string.IsNullOrWhiteSpace(path) && Directory.Exists(path) && !ViewModel.GameDirectories.Contains(path))
  121. {
  122. ViewModel.GameDirectories.Add(path);
  123. ViewModel.DirectoryChanged = true;
  124. }
  125. else
  126. {
  127. path = await new OpenFolderDialog().ShowAsync(this);
  128. if (!string.IsNullOrWhiteSpace(path))
  129. {
  130. ViewModel.GameDirectories.Add(path);
  131. ViewModel.DirectoryChanged = true;
  132. }
  133. }
  134. }
  135. private void RemoveButton_OnClick(object sender, RoutedEventArgs e)
  136. {
  137. int oldIndex = GameList.SelectedIndex;
  138. foreach (string path in new List<string>(GameList.SelectedItems.Cast<string>()))
  139. {
  140. ViewModel.GameDirectories.Remove(path);
  141. ViewModel.DirectoryChanged = true;
  142. }
  143. if (GameList.ItemCount > 0)
  144. {
  145. GameList.SelectedIndex = oldIndex < GameList.ItemCount ? oldIndex : 0;
  146. }
  147. }
  148. private void TimeZoneBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
  149. {
  150. if (e.AddedItems != null && e.AddedItems.Count > 0)
  151. {
  152. if (e.AddedItems[0] is TimeZone timeZone)
  153. {
  154. e.Handled = true;
  155. ViewModel.ValidateAndSetTimeZone(timeZone.Location);
  156. }
  157. }
  158. }
  159. private void TimeZoneBox_OnTextChanged(object sender, EventArgs e)
  160. {
  161. if (sender is AutoCompleteBox box)
  162. {
  163. if (box.SelectedItem != null && box.SelectedItem is TimeZone timeZone)
  164. {
  165. ViewModel.ValidateAndSetTimeZone(timeZone.Location);
  166. }
  167. }
  168. }
  169. protected override void OnClosed(EventArgs e)
  170. {
  171. ControllerSettings.Dispose();
  172. _currentAssigner?.Cancel();
  173. _currentAssigner = null;
  174. base.OnClosed(e);
  175. }
  176. }
  177. }