1
1
mirror of https://github.com/ryujinx-mirror/ryujinx.git synced 2025-10-03 10:15:51 -05:00

[Ryujinx] Address dotnet-format issues (#5395)

* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA2208 warnings

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address dotnet format CA1822 warnings

* Make dotnet format succeed in style mode

* Address dotnet format CA2208 warnings properly

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Another rebase, another dotnet format run

* Run dotnet format whitespace after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Fix build issues

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Second dotnet format pass

* Update src/Ryujinx/Modules/Updater/Updater.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Add trailing commas and improve formatting

* Fix formatting and naming issues

* Rename nvStutterWorkaround to nvidiaStutterWorkaround

* Use using declarations and extend resource lifetimes

* Fix GTK issues

* Add formatting for generated files

* Add trailing commas

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
This commit is contained in:
TSRBerry
2023-07-02 00:25:07 +02:00
committed by GitHub
parent 02b5c7ea89
commit 0684b00b3c
39 changed files with 1891 additions and 1830 deletions

View File

@@ -7,65 +7,63 @@ namespace Ryujinx.Ui.Windows
{
public partial class AboutWindow : Window
{
private Box _mainBox;
private Box _leftBox;
private Box _logoBox;
private Image _ryujinxLogo;
private Box _logoTextBox;
private Label _ryujinxLabel;
private Label _ryujinxPhoneticLabel;
private EventBox _ryujinxLink;
private Label _ryujinxLinkLabel;
private Label _versionLabel;
private Label _disclaimerLabel;
private EventBox _amiiboApiLink;
private Label _amiiboApiLinkLabel;
private Box _socialBox;
private EventBox _patreonEventBox;
private Box _patreonBox;
private Image _patreonLogo;
private Label _patreonLabel;
private EventBox _githubEventBox;
private Box _githubBox;
private Image _githubLogo;
private Label _githubLabel;
private Box _discordBox;
private EventBox _discordEventBox;
private Image _discordLogo;
private Label _discordLabel;
private EventBox _twitterEventBox;
private Box _twitterBox;
private Image _twitterLogo;
private Label _twitterLabel;
private Separator _separator;
private Box _rightBox;
private Label _aboutLabel;
private Label _aboutDescriptionLabel;
private Label _createdByLabel;
private TextView _createdByText;
private EventBox _contributorsEventBox;
private Label _contributorsLinkLabel;
private Label _patreonNamesLabel;
private Box _mainBox;
private Box _leftBox;
private Box _logoBox;
private Image _ryujinxLogo;
private Box _logoTextBox;
private Label _ryujinxLabel;
private Label _ryujinxPhoneticLabel;
private EventBox _ryujinxLink;
private Label _ryujinxLinkLabel;
private Label _versionLabel;
private Label _disclaimerLabel;
private EventBox _amiiboApiLink;
private Label _amiiboApiLinkLabel;
private Box _socialBox;
private EventBox _patreonEventBox;
private Box _patreonBox;
private Image _patreonLogo;
private Label _patreonLabel;
private EventBox _githubEventBox;
private Box _githubBox;
private Image _githubLogo;
private Label _githubLabel;
private Box _discordBox;
private EventBox _discordEventBox;
private Image _discordLogo;
private Label _discordLabel;
private EventBox _twitterEventBox;
private Box _twitterBox;
private Image _twitterLogo;
private Label _twitterLabel;
private Separator _separator;
private Box _rightBox;
private Label _aboutLabel;
private Label _aboutDescriptionLabel;
private Label _createdByLabel;
private TextView _createdByText;
private EventBox _contributorsEventBox;
private Label _contributorsLinkLabel;
private Label _patreonNamesLabel;
private ScrolledWindow _patreonNamesScrolled;
private TextView _patreonNamesText;
private EventBox _changelogEventBox;
private Label _changelogLinkLabel;
private TextView _patreonNamesText;
private EventBox _changelogEventBox;
private Label _changelogLinkLabel;
private void InitializeComponent()
{
#pragma warning disable CS0612
//
// AboutWindow
//
CanFocus = false;
Resizable = false;
Modal = true;
CanFocus = false;
Resizable = false;
Modal = true;
WindowPosition = WindowPosition.Center;
DefaultWidth = 800;
DefaultHeight = 450;
TypeHint = Gdk.WindowTypeHint.Dialog;
DefaultWidth = 800;
DefaultHeight = 450;
TypeHint = Gdk.WindowTypeHint.Dialog;
//
// _mainBox
@@ -77,9 +75,9 @@ namespace Ryujinx.Ui.Windows
//
_leftBox = new Box(Orientation.Vertical, 0)
{
Margin = 15,
MarginLeft = 30,
MarginRight = 0
Margin = 15,
MarginStart = 30,
MarginEnd = 0,
};
//
@@ -92,8 +90,8 @@ namespace Ryujinx.Ui.Windows
//
_ryujinxLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png", 100, 100))
{
Margin = 10,
MarginLeft = 15
Margin = 10,
MarginStart = 15,
};
//
@@ -106,9 +104,9 @@ namespace Ryujinx.Ui.Windows
//
_ryujinxLabel = new Label("Ryujinx")
{
MarginTop = 15,
Justify = Justification.Center,
Attributes = new AttrList()
MarginTop = 15,
Justify = Justification.Center,
Attributes = new AttrList(),
};
_ryujinxLabel.Attributes.Insert(new Pango.AttrScale(2.7f));
@@ -117,7 +115,7 @@ namespace Ryujinx.Ui.Windows
//
_ryujinxPhoneticLabel = new Label("(REE-YOU-JINX)")
{
Justify = Justification.Center
Justify = Justification.Center,
};
//
@@ -135,8 +133,8 @@ namespace Ryujinx.Ui.Windows
_ryujinxLinkLabel = new Label("www.ryujinx.org")
{
TooltipText = "Click to open the Ryujinx website in your default browser.",
Justify = Justification.Center,
Attributes = new AttrList()
Justify = Justification.Center,
Attributes = new AttrList(),
};
_ryujinxLinkLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single));
@@ -145,9 +143,9 @@ namespace Ryujinx.Ui.Windows
//
_versionLabel = new Label(Program.Version)
{
Expand = true,
Expand = true,
Justify = Justification.Center,
Margin = 5
Margin = 5,
};
//
@@ -163,7 +161,7 @@ namespace Ryujinx.Ui.Windows
{
TooltipText = "Click to open the changelog for this version in your default browser.",
Justify = Justification.Center,
Attributes = new AttrList()
Attributes = new AttrList(),
};
_changelogLinkLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single));
@@ -172,10 +170,10 @@ namespace Ryujinx.Ui.Windows
//
_disclaimerLabel = new Label("Ryujinx is not affiliated with Nintendo™,\nor any of its partners, in any way.")
{
Expand = true,
Justify = Justification.Center,
Margin = 5,
Attributes = new AttrList()
Expand = true,
Justify = Justification.Center,
Margin = 5,
Attributes = new AttrList(),
};
_disclaimerLabel.Attributes.Insert(new Pango.AttrScale(0.8f));
@@ -184,7 +182,7 @@ namespace Ryujinx.Ui.Windows
//
_amiiboApiLink = new EventBox()
{
Margin = 5
Margin = 5,
};
_amiiboApiLink.ButtonPressEvent += AmiiboApiButton_Pressed;
@@ -194,8 +192,8 @@ namespace Ryujinx.Ui.Windows
_amiiboApiLinkLabel = new Label("AmiiboAPI (www.amiiboapi.com) is used\nin our Amiibo emulation.")
{
TooltipText = "Click to open the AmiiboAPI website in your default browser.",
Justify = Justification.Center,
Attributes = new AttrList()
Justify = Justification.Center,
Attributes = new AttrList(),
};
_amiiboApiLinkLabel.Attributes.Insert(new Pango.AttrScale(0.9f));
@@ -204,8 +202,8 @@ namespace Ryujinx.Ui.Windows
//
_socialBox = new Box(Orientation.Horizontal, 0)
{
Margin = 25,
MarginBottom = 10
Margin = 25,
MarginBottom = 10,
};
//
@@ -213,7 +211,7 @@ namespace Ryujinx.Ui.Windows
//
_patreonEventBox = new EventBox()
{
TooltipText = "Click to open the Ryujinx Patreon page in your default browser."
TooltipText = "Click to open the Ryujinx Patreon page in your default browser.",
};
_patreonEventBox.ButtonPressEvent += PatreonButton_Pressed;
@@ -227,7 +225,7 @@ namespace Ryujinx.Ui.Windows
//
_patreonLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Patreon_Light.png", 30, 30))
{
Margin = 10
Margin = 10,
};
//
@@ -235,7 +233,7 @@ namespace Ryujinx.Ui.Windows
//
_patreonLabel = new Label("Patreon")
{
Justify = Justification.Center
Justify = Justification.Center,
};
//
@@ -243,7 +241,7 @@ namespace Ryujinx.Ui.Windows
//
_githubEventBox = new EventBox()
{
TooltipText = "Click to open the Ryujinx GitHub page in your default browser."
TooltipText = "Click to open the Ryujinx GitHub page in your default browser.",
};
_githubEventBox.ButtonPressEvent += GitHubButton_Pressed;
@@ -257,7 +255,7 @@ namespace Ryujinx.Ui.Windows
//
_githubLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_GitHub_Light.png", 30, 30))
{
Margin = 10
Margin = 10,
};
//
@@ -265,7 +263,7 @@ namespace Ryujinx.Ui.Windows
//
_githubLabel = new Label("GitHub")
{
Justify = Justification.Center
Justify = Justification.Center,
};
//
@@ -278,7 +276,7 @@ namespace Ryujinx.Ui.Windows
//
_discordEventBox = new EventBox()
{
TooltipText = "Click to open an invite to the Ryujinx Discord server in your default browser."
TooltipText = "Click to open an invite to the Ryujinx Discord server in your default browser.",
};
_discordEventBox.ButtonPressEvent += DiscordButton_Pressed;
@@ -287,7 +285,7 @@ namespace Ryujinx.Ui.Windows
//
_discordLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Discord_Light.png", 30, 30))
{
Margin = 10
Margin = 10,
};
//
@@ -295,7 +293,7 @@ namespace Ryujinx.Ui.Windows
//
_discordLabel = new Label("Discord")
{
Justify = Justification.Center
Justify = Justification.Center,
};
//
@@ -303,7 +301,7 @@ namespace Ryujinx.Ui.Windows
//
_twitterEventBox = new EventBox()
{
TooltipText = "Click to open the Ryujinx Twitter page in your default browser."
TooltipText = "Click to open the Ryujinx Twitter page in your default browser.",
};
_twitterEventBox.ButtonPressEvent += TwitterButton_Pressed;
@@ -317,7 +315,7 @@ namespace Ryujinx.Ui.Windows
//
_twitterLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Twitter_Light.png", 30, 30))
{
Margin = 10
Margin = 10,
};
//
@@ -325,7 +323,7 @@ namespace Ryujinx.Ui.Windows
//
_twitterLabel = new Label("Twitter")
{
Justify = Justification.Center
Justify = Justification.Center,
};
//
@@ -333,7 +331,7 @@ namespace Ryujinx.Ui.Windows
//
_separator = new Separator(Orientation.Vertical)
{
Margin = 15
Margin = 15,
};
//
@@ -341,8 +339,8 @@ namespace Ryujinx.Ui.Windows
//
_rightBox = new Box(Orientation.Vertical, 0)
{
Margin = 15,
MarginTop = 40
Margin = 15,
MarginTop = 40,
};
//
@@ -350,8 +348,8 @@ namespace Ryujinx.Ui.Windows
//
_aboutLabel = new Label("About :")
{
Halign = Align.Start,
Attributes = new AttrList()
Halign = Align.Start,
Attributes = new AttrList(),
};
_aboutLabel.Attributes.Insert(new Pango.AttrWeight(Weight.Bold));
_aboutLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single));
@@ -365,7 +363,7 @@ namespace Ryujinx.Ui.Windows
"Developers interested in contributing can find out more on our GitHub or Discord.")
{
Margin = 15,
Halign = Align.Start
Halign = Align.Start,
};
//
@@ -373,8 +371,8 @@ namespace Ryujinx.Ui.Windows
//
_createdByLabel = new Label("Maintained by :")
{
Halign = Align.Start,
Attributes = new AttrList()
Halign = Align.Start,
Attributes = new AttrList(),
};
_createdByLabel.Attributes.Insert(new Pango.AttrWeight(Weight.Bold));
_createdByLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single));
@@ -384,11 +382,11 @@ namespace Ryujinx.Ui.Windows
//
_createdByText = new TextView()
{
WrapMode = Gtk.WrapMode.Word,
Editable = false,
WrapMode = Gtk.WrapMode.Word,
Editable = false,
CursorVisible = false,
Margin = 15,
MarginRight = 30
Margin = 15,
MarginEnd = 30,
};
_createdByText.Buffer.Text = "gdkchan, Ac_K, Thog, rip in peri peri, LDj3SNuD, emmaus, Thealexbarney, Xpl0itR, GoffyDude, »jD« and more...";
@@ -404,9 +402,9 @@ namespace Ryujinx.Ui.Windows
_contributorsLinkLabel = new Label("See All Contributors...")
{
TooltipText = "Click to open the Contributors page in your default browser.",
MarginRight = 30,
Halign = Align.End,
Attributes = new AttrList()
MarginEnd = 30,
Halign = Align.End,
Attributes = new AttrList(),
};
_contributorsLinkLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single));
@@ -415,8 +413,8 @@ namespace Ryujinx.Ui.Windows
//
_patreonNamesLabel = new Label("Supported on Patreon by :")
{
Halign = Align.Start,
Attributes = new AttrList()
Halign = Align.Start,
Attributes = new AttrList(),
};
_patreonNamesLabel.Attributes.Insert(new Pango.AttrWeight(Weight.Bold));
_patreonNamesLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single));
@@ -426,10 +424,10 @@ namespace Ryujinx.Ui.Windows
//
_patreonNamesScrolled = new ScrolledWindow()
{
Margin = 15,
MarginRight = 30,
Expand = true,
ShadowType = ShadowType.In
Margin = 15,
MarginEnd = 30,
Expand = true,
ShadowType = ShadowType.In,
};
_patreonNamesScrolled.SetPolicy(PolicyType.Never, PolicyType.Automatic);
@@ -438,13 +436,11 @@ namespace Ryujinx.Ui.Windows
//
_patreonNamesText = new TextView()
{
WrapMode = Gtk.WrapMode.Word
WrapMode = Gtk.WrapMode.Word,
};
_patreonNamesText.Buffer.Text = "Loading...";
_patreonNamesText.SetProperty("editable", new GLib.Value(false));
#pragma warning restore CS0612
ShowComponent();
}
@@ -512,4 +508,4 @@ namespace Ryujinx.Ui.Windows
ShowAll();
}
}
}
}

View File

@@ -25,7 +25,7 @@ namespace Ryujinx.Ui.Windows
_patreonNamesText.Buffer.Text = "Connection Error.";
}
HttpClient httpClient = new HttpClient();
HttpClient httpClient = new();
try
{
@@ -82,4 +82,4 @@ namespace Ryujinx.Ui.Windows
OpenHelper.OpenUrl("https://github.com/Ryujinx/Ryujinx/wiki/Changelog#ryujinx-changelog");
}
}
}
}

View File

@@ -4,37 +4,35 @@ namespace Ryujinx.Ui.Windows
{
public partial class AmiiboWindow : Window
{
private Box _mainBox;
private ButtonBox _buttonBox;
private Button _scanButton;
private Button _cancelButton;
private CheckButton _randomUuidCheckBox;
private Box _amiiboBox;
private Box _amiiboHeadBox;
private Box _amiiboSeriesBox;
private Label _amiiboSeriesLabel;
private Box _mainBox;
private ButtonBox _buttonBox;
private Button _scanButton;
private Button _cancelButton;
private CheckButton _randomUuidCheckBox;
private Box _amiiboBox;
private Box _amiiboHeadBox;
private Box _amiiboSeriesBox;
private Label _amiiboSeriesLabel;
private ComboBoxText _amiiboSeriesComboBox;
private Box _amiiboCharsBox;
private Label _amiiboCharsLabel;
private Box _amiiboCharsBox;
private Label _amiiboCharsLabel;
private ComboBoxText _amiiboCharsComboBox;
private CheckButton _showAllCheckBox;
private Image _amiiboImage;
private Label _gameUsageLabel;
private CheckButton _showAllCheckBox;
private Image _amiiboImage;
private Label _gameUsageLabel;
private void InitializeComponent()
{
#pragma warning disable CS0612
//
// AmiiboWindow
//
CanFocus = false;
Resizable = false;
Modal = true;
CanFocus = false;
Resizable = false;
Modal = true;
WindowPosition = WindowPosition.Center;
DefaultWidth = 600;
DefaultHeight = 470;
TypeHint = Gdk.WindowTypeHint.Dialog;
DefaultWidth = 600;
DefaultHeight = 470;
TypeHint = Gdk.WindowTypeHint.Dialog;
//
// _mainBox
@@ -46,8 +44,8 @@ namespace Ryujinx.Ui.Windows
//
_buttonBox = new ButtonBox(Orientation.Horizontal)
{
Margin = 20,
LayoutStyle = ButtonBoxStyle.End
Margin = 20,
LayoutStyle = ButtonBoxStyle.End,
};
//
@@ -55,10 +53,10 @@ namespace Ryujinx.Ui.Windows
//
_scanButton = new Button()
{
Label = "Scan It!",
CanFocus = true,
Label = "Scan It!",
CanFocus = true,
ReceivesDefault = true,
MarginLeft = 10
MarginStart = 10,
};
_scanButton.Clicked += ScanButton_Pressed;
@@ -67,8 +65,8 @@ namespace Ryujinx.Ui.Windows
//
_randomUuidCheckBox = new CheckButton()
{
Label = "Hack: Use Random Tag Uuid",
TooltipText = "This allows multiple scans of a single Amiibo.\n(used in The Legend of Zelda: Breath of the Wild)"
Label = "Hack: Use Random Tag Uuid",
TooltipText = "This allows multiple scans of a single Amiibo.\n(used in The Legend of Zelda: Breath of the Wild)",
};
//
@@ -76,10 +74,10 @@ namespace Ryujinx.Ui.Windows
//
_cancelButton = new Button()
{
Label = "Cancel",
CanFocus = true,
Label = "Cancel",
CanFocus = true,
ReceivesDefault = true,
MarginLeft = 10
MarginStart = 10,
};
_cancelButton.Clicked += CancelButton_Pressed;
@@ -94,7 +92,7 @@ namespace Ryujinx.Ui.Windows
_amiiboHeadBox = new Box(Orientation.Horizontal, 0)
{
Margin = 20,
Hexpand = true
Hexpand = true,
};
//
@@ -102,7 +100,7 @@ namespace Ryujinx.Ui.Windows
//
_amiiboSeriesBox = new Box(Orientation.Horizontal, 0)
{
Hexpand = true
Hexpand = true,
};
//
@@ -120,7 +118,7 @@ namespace Ryujinx.Ui.Windows
//
_amiiboCharsBox = new Box(Orientation.Horizontal, 0)
{
Hexpand = true
Hexpand = true,
};
//
@@ -138,7 +136,7 @@ namespace Ryujinx.Ui.Windows
//
_showAllCheckBox = new CheckButton()
{
Label = "Show All Amiibo"
Label = "Show All Amiibo",
};
//
@@ -147,7 +145,7 @@ namespace Ryujinx.Ui.Windows
_amiiboImage = new Image()
{
HeightRequest = 350,
WidthRequest = 350
WidthRequest = 350,
};
//
@@ -155,11 +153,9 @@ namespace Ryujinx.Ui.Windows
//
_gameUsageLabel = new Label("")
{
MarginTop = 20
MarginTop = 20,
};
#pragma warning restore CS0612
ShowComponent();
}
@@ -191,4 +187,4 @@ namespace Ryujinx.Ui.Windows
ShowAll();
}
}
}
}

View File

@@ -14,21 +14,19 @@ using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using AmiiboApi = Ryujinx.Ui.Common.Models.Amiibo.AmiiboApi;
using AmiiboJsonSerializerContext = Ryujinx.Ui.Common.Models.Amiibo.AmiiboJsonSerializerContext;
namespace Ryujinx.Ui.Windows
{
public partial class AmiiboWindow : Window
{
private const string DEFAULT_JSON = "{ \"amiibo\": [] }";
private const string DefaultJson = "{ \"amiibo\": [] }";
public string AmiiboId { get; private set; }
public int DeviceId { get; set; }
public string TitleId { get; set; }
public string LastScannedAmiiboId { get; set; }
public bool LastScannedAmiiboShowAll { get; set; }
public int DeviceId { get; set; }
public string TitleId { get; set; }
public string LastScannedAmiiboId { get; set; }
public bool LastScannedAmiiboShowAll { get; set; }
public ResponseType Response { get; private set; }
@@ -41,13 +39,13 @@ namespace Ryujinx.Ui.Windows
}
private readonly HttpClient _httpClient;
private readonly string _amiiboJsonPath;
private readonly string _amiiboJsonPath;
private readonly byte[] _amiiboLogoBytes;
private List<AmiiboApi> _amiiboList;
private static readonly AmiiboJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
private static readonly AmiiboJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
public AmiiboWindow() : base($"Ryujinx {Program.Version} - Amiibo")
{
@@ -57,18 +55,18 @@ namespace Ryujinx.Ui.Windows
_httpClient = new HttpClient()
{
Timeout = TimeSpan.FromSeconds(30)
Timeout = TimeSpan.FromSeconds(30),
};
Directory.CreateDirectory(System.IO.Path.Join(AppDataManager.BaseDirPath, "system", "amiibo"));
_amiiboJsonPath = System.IO.Path.Join(AppDataManager.BaseDirPath, "system", "amiibo", "Amiibo.json");
_amiiboList = new List<AmiiboApi>();
_amiiboList = new List<AmiiboApi>();
_amiiboLogoBytes = EmbeddedResources.Read("Ryujinx.Ui.Common/Resources/Logo_Amiibo.png");
_amiiboLogoBytes = EmbeddedResources.Read("Ryujinx.Ui.Common/Resources/Logo_Amiibo.png");
_amiiboImage.Pixbuf = new Gdk.Pixbuf(_amiiboLogoBytes);
_scanButton.Sensitive = false;
_scanButton.Sensitive = false;
_randomUuidCheckBox.Sensitive = false;
_ = LoadContentAsync();
@@ -76,13 +74,13 @@ namespace Ryujinx.Ui.Windows
private async Task LoadContentAsync()
{
string amiiboJsonString = DEFAULT_JSON;
string amiiboJsonString = DefaultJson;
if (File.Exists(_amiiboJsonPath))
{
amiiboJsonString = await File.ReadAllTextAsync(_amiiboJsonPath);
if (await NeedsUpdate(JsonHelper.Deserialize(amiiboJsonString, SerializerContext.AmiiboJson).LastUpdated))
if (await NeedsUpdate(JsonHelper.Deserialize(amiiboJsonString, _serializerContext.AmiiboJson).LastUpdated))
{
amiiboJsonString = await DownloadAmiiboJson();
}
@@ -103,7 +101,7 @@ namespace Ryujinx.Ui.Windows
}
}
_amiiboList = JsonHelper.Deserialize(amiiboJsonString, SerializerContext.AmiiboJson).Amiibo;
_amiiboList = JsonHelper.Deserialize(amiiboJsonString, _serializerContext.AmiiboJson).Amiibo;
_amiiboList = _amiiboList.OrderBy(amiibo => amiibo.AmiiboSeries).ToList();
if (LastScannedAmiiboShowAll)
@@ -118,7 +116,7 @@ namespace Ryujinx.Ui.Windows
private void ParseAmiiboData()
{
List<string> comboxItemList = new List<string>();
List<string> comboxItemList = new();
for (int i = 0; i < _amiiboList.Count; i++)
{
@@ -149,7 +147,7 @@ namespace Ryujinx.Ui.Windows
}
_amiiboSeriesComboBox.Changed += SeriesComboBox_Changed;
_amiiboCharsComboBox.Changed += CharacterComboBox_Changed;
_amiiboCharsComboBox.Changed += CharacterComboBox_Changed;
if (LastScannedAmiiboId != "")
{
@@ -219,7 +217,7 @@ namespace Ryujinx.Ui.Windows
Close();
}
return DEFAULT_JSON;
return DefaultJson;
}
private async Task UpdateAmiiboPreview(string imageUrl)
@@ -228,14 +226,14 @@ namespace Ryujinx.Ui.Windows
if (response.IsSuccessStatusCode)
{
byte[] amiiboPreviewBytes = await response.Content.ReadAsByteArrayAsync();
Gdk.Pixbuf amiiboPreview = new Gdk.Pixbuf(amiiboPreviewBytes);
byte[] amiiboPreviewBytes = await response.Content.ReadAsByteArrayAsync();
Gdk.Pixbuf amiiboPreview = new(amiiboPreviewBytes);
float ratio = Math.Min((float)_amiiboImage.AllocatedWidth / amiiboPreview.Width,
float ratio = Math.Min((float)_amiiboImage.AllocatedWidth / amiiboPreview.Width,
(float)_amiiboImage.AllocatedHeight / amiiboPreview.Height);
int resizeHeight = (int)(amiiboPreview.Height * ratio);
int resizeWidth = (int)(amiiboPreview.Width * ratio);
int resizeWidth = (int)(amiiboPreview.Width * ratio);
_amiiboImage.Pixbuf = amiiboPreview.ScaleSimple(resizeWidth, resizeHeight, Gdk.InterpType.Bilinear);
}
@@ -245,7 +243,7 @@ namespace Ryujinx.Ui.Windows
}
}
private void ShowInfoDialog()
private static void ShowInfoDialog()
{
GtkDialog.CreateInfoDialog($"Amiibo API", "Unable to connect to Amiibo API server. The service may be down or you may need to verify your internet connection is online.");
}
@@ -261,7 +259,7 @@ namespace Ryujinx.Ui.Windows
List<AmiiboApi> amiiboSortedList = _amiiboList.Where(amiibo => amiibo.AmiiboSeries == _amiiboSeriesComboBox.ActiveId).OrderBy(amiibo => amiibo.Name).ToList();
List<string> comboxItemList = new List<string>();
List<string> comboxItemList = new();
for (int i = 0; i < amiiboSortedList.Count; i++)
{
@@ -295,7 +293,7 @@ namespace Ryujinx.Ui.Windows
_amiiboCharsComboBox.Active = 0;
_scanButton.Sensitive = true;
_scanButton.Sensitive = true;
_randomUuidCheckBox.Sensitive = true;
}
@@ -346,12 +344,12 @@ namespace Ryujinx.Ui.Windows
_amiiboImage.Pixbuf = new Gdk.Pixbuf(_amiiboLogoBytes);
_amiiboSeriesComboBox.Changed -= SeriesComboBox_Changed;
_amiiboCharsComboBox.Changed -= CharacterComboBox_Changed;
_amiiboCharsComboBox.Changed -= CharacterComboBox_Changed;
_amiiboSeriesComboBox.RemoveAll();
_amiiboCharsComboBox.RemoveAll();
_scanButton.Sensitive = false;
_scanButton.Sensitive = false;
_randomUuidCheckBox.Sensitive = false;
new Task(() => ParseAmiiboData()).Start();
@@ -368,8 +366,8 @@ namespace Ryujinx.Ui.Windows
private void CancelButton_Pressed(object sender, EventArgs args)
{
AmiiboId = "";
LastScannedAmiiboId = "";
AmiiboId = "";
LastScannedAmiiboId = "";
LastScannedAmiiboShowAll = false;
Response = ResponseType.Cancel;
@@ -384,4 +382,4 @@ namespace Ryujinx.Ui.Windows
base.Dispose(disposing);
}
}
}
}

View File

@@ -18,7 +18,6 @@ using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Image = SixLabors.ImageSharp.Image;
namespace Ryujinx.Ui.Windows
@@ -26,23 +25,23 @@ namespace Ryujinx.Ui.Windows
public class AvatarWindow : Window
{
public byte[] SelectedProfileImage;
public bool NewUser;
public bool NewUser;
private static Dictionary<string, byte[]> _avatarDict = new Dictionary<string, byte[]>();
private static readonly Dictionary<string, byte[]> _avatarDict = new();
private ListStore _listStore;
private IconView _iconView;
private Button _setBackgroungColorButton;
private Gdk.RGBA _backgroundColor;
private readonly ListStore _listStore;
private readonly IconView _iconView;
private readonly Button _setBackgroungColorButton;
private Gdk.RGBA _backgroundColor;
public AvatarWindow() : base($"Ryujinx {Program.Version} - Manage Accounts - Avatar")
{
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
CanFocus = false;
CanFocus = false;
Resizable = false;
Modal = true;
TypeHint = Gdk.WindowTypeHint.Dialog;
Modal = true;
TypeHint = Gdk.WindowTypeHint.Dialog;
SetDefaultSize(740, 400);
SetPosition(WindowPosition.Center);
@@ -50,54 +49,56 @@ namespace Ryujinx.Ui.Windows
Box vbox = new(Orientation.Vertical, 0);
Add(vbox);
ScrolledWindow scrolledWindow = new ScrolledWindow
ScrolledWindow scrolledWindow = new()
{
ShadowType = ShadowType.EtchedIn
ShadowType = ShadowType.EtchedIn,
};
scrolledWindow.SetPolicy(PolicyType.Automatic, PolicyType.Automatic);
Box hbox = new(Orientation.Horizontal, 0);
Button chooseButton = new Button()
Button chooseButton = new()
{
Label = "Choose",
CanFocus = true,
ReceivesDefault = true
Label = "Choose",
CanFocus = true,
ReceivesDefault = true,
};
chooseButton.Clicked += ChooseButton_Pressed;
_setBackgroungColorButton = new Button()
{
Label = "Set Background Color",
CanFocus = true
Label = "Set Background Color",
CanFocus = true,
};
_setBackgroungColorButton.Clicked += SetBackgroungColorButton_Pressed;
_backgroundColor.Red = 1;
_backgroundColor.Red = 1;
_backgroundColor.Green = 1;
_backgroundColor.Blue = 1;
_backgroundColor.Blue = 1;
_backgroundColor.Alpha = 1;
Button closeButton = new Button()
Button closeButton = new()
{
Label = "Close",
CanFocus = true
Label = "Close",
CanFocus = true,
};
closeButton.Clicked += CloseButton_Pressed;
vbox.PackStart(scrolledWindow, true, true, 0);
hbox.PackStart(chooseButton, true, true, 0);
hbox.PackStart(_setBackgroungColorButton, true, true, 0);
hbox.PackStart(closeButton, true, true, 0);
vbox.PackStart(hbox, false, false, 0);
vbox.PackStart(scrolledWindow, true, true, 0);
hbox.PackStart(chooseButton, true, true, 0);
hbox.PackStart(_setBackgroungColorButton, true, true, 0);
hbox.PackStart(closeButton, true, true, 0);
vbox.PackStart(hbox, false, false, 0);
_listStore = new ListStore(typeof(string), typeof(Gdk.Pixbuf));
_listStore.SetSortColumnId(0, SortType.Ascending);
_iconView = new IconView(_listStore);
_iconView.ItemWidth = 64;
_iconView.ItemPadding = 10;
_iconView.PixbufColumn = 1;
_iconView = new IconView(_listStore)
{
ItemWidth = 64,
ItemPadding = 10,
PixbufColumn = 1,
};
_iconView.SelectionChanged += IconView_SelectionChanged;
@@ -118,39 +119,36 @@ namespace Ryujinx.Ui.Windows
}
string contentPath = contentManager.GetInstalledContentPath(0x010000000000080A, StorageId.BuiltInSystem, NcaContentType.Data);
string avatarPath = virtualFileSystem.SwitchPathToSystemPath(contentPath);
string avatarPath = virtualFileSystem.SwitchPathToSystemPath(contentPath);
if (!string.IsNullOrWhiteSpace(avatarPath))
{
using (IStorage ncaFileStream = new LocalStorage(avatarPath, FileAccess.Read, FileMode.Open))
using IStorage ncaFileStream = new LocalStorage(avatarPath, FileAccess.Read, FileMode.Open);
Nca nca = new(virtualFileSystem.KeySet, ncaFileStream);
IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
foreach (var item in romfs.EnumerateEntries())
{
Nca nca = new Nca(virtualFileSystem.KeySet, ncaFileStream);
IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
// TODO: Parse DatabaseInfo.bin and table.bin files for more accuracy.
foreach (var item in romfs.EnumerateEntries())
if (item.Type == DirectoryEntryType.File && item.FullPath.Contains("chara") && item.FullPath.Contains("szs"))
{
// TODO: Parse DatabaseInfo.bin and table.bin files for more accuracy.
using var file = new UniqueRef<IFile>();
if (item.Type == DirectoryEntryType.File && item.FullPath.Contains("chara") && item.FullPath.Contains("szs"))
{
using var file = new UniqueRef<IFile>();
romfs.OpenFile(ref file.Ref, ("/" + item.FullPath).ToU8Span(), OpenMode.Read).ThrowIfFailure();
romfs.OpenFile(ref file.Ref, ("/" + item.FullPath).ToU8Span(), OpenMode.Read).ThrowIfFailure();
using MemoryStream stream = MemoryStreamManager.Shared.GetStream();
using MemoryStream streamPng = MemoryStreamManager.Shared.GetStream();
file.Get.AsStream().CopyTo(stream);
using (MemoryStream stream = MemoryStreamManager.Shared.GetStream())
using (MemoryStream streamPng = MemoryStreamManager.Shared.GetStream())
{
file.Get.AsStream().CopyTo(stream);
stream.Position = 0;
stream.Position = 0;
Image avatarImage = Image.LoadPixelData<Rgba32>(DecompressYaz0(stream), 256, 256);
Image avatarImage = Image.LoadPixelData<Rgba32>(DecompressYaz0(stream), 256, 256);
avatarImage.SaveAsPng(streamPng);
avatarImage.SaveAsPng(streamPng);
_avatarDict.Add(item.FullPath, streamPng.ToArray());
}
}
_avatarDict.Add(item.FullPath, streamPng.ToArray());
}
}
}
@@ -165,23 +163,24 @@ namespace Ryujinx.Ui.Windows
_listStore.AppendValues(avatar.Key, new Gdk.Pixbuf(ProcessImage(avatar.Value), 96, 96));
}
_iconView.SelectPath(new TreePath(new int[] { 0 }));
_iconView.SelectPath(new TreePath(new[] { 0 }));
}
private byte[] ProcessImage(byte[] data)
{
using (MemoryStream streamJpg = MemoryStreamManager.Shared.GetStream())
{
Image avatarImage = Image.Load(data, new PngDecoder());
using MemoryStream streamJpg = MemoryStreamManager.Shared.GetStream();
avatarImage.Mutate(x => x.BackgroundColor(new Rgba32((byte)(_backgroundColor.Red * 255),
(byte)(_backgroundColor.Green * 255),
(byte)(_backgroundColor.Blue * 255),
(byte)(_backgroundColor.Alpha * 255))));
avatarImage.SaveAsJpeg(streamJpg);
Image avatarImage = Image.Load(data, new PngDecoder());
return streamJpg.ToArray();
}
avatarImage.Mutate(x => x.BackgroundColor(new Rgba32(
(byte)(_backgroundColor.Red * 255),
(byte)(_backgroundColor.Green * 255),
(byte)(_backgroundColor.Blue * 255),
(byte)(_backgroundColor.Alpha * 255)
)));
avatarImage.SaveAsJpeg(streamJpg);
return streamJpg.ToArray();
}
private void CloseButton_Pressed(object sender, EventArgs e)
@@ -203,20 +202,19 @@ namespace Ryujinx.Ui.Windows
private void SetBackgroungColorButton_Pressed(object sender, EventArgs e)
{
using (ColorChooserDialog colorChooserDialog = new ColorChooserDialog("Set Background Color", this))
using ColorChooserDialog colorChooserDialog = new("Set Background Color", this);
colorChooserDialog.UseAlpha = false;
colorChooserDialog.Rgba = _backgroundColor;
if (colorChooserDialog.Run() == (int)ResponseType.Ok)
{
colorChooserDialog.UseAlpha = false;
colorChooserDialog.Rgba = _backgroundColor;
if (colorChooserDialog.Run() == (int)ResponseType.Ok)
{
_backgroundColor = colorChooserDialog.Rgba;
_backgroundColor = colorChooserDialog.Rgba;
ProcessAvatars();
}
colorChooserDialog.Hide();
ProcessAvatars();
}
colorChooserDialog.Hide();
}
private void ChooseButton_Pressed(object sender, EventArgs e)
@@ -226,69 +224,68 @@ namespace Ryujinx.Ui.Windows
private static byte[] DecompressYaz0(Stream stream)
{
using (BinaryReader reader = new BinaryReader(stream))
using BinaryReader reader = new(stream);
reader.ReadInt32(); // Magic
uint decodedLength = BinaryPrimitives.ReverseEndianness(reader.ReadUInt32());
reader.ReadInt64(); // Padding
byte[] input = new byte[stream.Length - stream.Position];
stream.Read(input, 0, input.Length);
long inputOffset = 0;
byte[] output = new byte[decodedLength];
long outputOffset = 0;
ushort mask = 0;
byte header = 0;
while (outputOffset < decodedLength)
{
reader.ReadInt32(); // Magic
uint decodedLength = BinaryPrimitives.ReverseEndianness(reader.ReadUInt32());
reader.ReadInt64(); // Padding
byte[] input = new byte[stream.Length - stream.Position];
stream.Read(input, 0, input.Length);
long inputOffset = 0;
byte[] output = new byte[decodedLength];
long outputOffset = 0;
ushort mask = 0;
byte header = 0;
while (outputOffset < decodedLength)
if ((mask >>= 1) == 0)
{
if ((mask >>= 1) == 0)
header = input[inputOffset++];
mask = 0x80;
}
if ((header & mask) > 0)
{
if (outputOffset == output.Length)
{
header = input[inputOffset++];
mask = 0x80;
break;
}
if ((header & mask) > 0)
{
if (outputOffset == output.Length)
{
break;
}
output[outputOffset++] = input[inputOffset++];
}
else
{
byte byte1 = input[inputOffset++];
byte byte2 = input[inputOffset++];
output[outputOffset++] = input[inputOffset++];
int dist = ((byte1 & 0xF) << 8) | byte2;
int position = (int)outputOffset - (dist + 1);
int length = byte1 >> 4;
if (length == 0)
{
length = input[inputOffset++] + 0x12;
}
else
{
byte byte1 = input[inputOffset++];
byte byte2 = input[inputOffset++];
length += 2;
}
int dist = ((byte1 & 0xF) << 8) | byte2;
int position = (int)outputOffset - (dist + 1);
int length = byte1 >> 4;
if (length == 0)
{
length = input[inputOffset++] + 0x12;
}
else
{
length += 2;
}
while (length-- > 0)
{
output[outputOffset++] = output[position++];
}
while (length-- > 0)
{
output[outputOffset++] = output[position++];
}
}
return output;
}
return output;
}
}
}
}

View File

@@ -6,7 +6,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using GUI = Gtk.Builder.ObjectAttribute;
namespace Ryujinx.Ui.Windows
@@ -16,11 +15,11 @@ namespace Ryujinx.Ui.Windows
private readonly string _enabledCheatsPath;
private readonly bool _noCheatsFound;
#pragma warning disable CS0649, IDE0044
[GUI] Label _baseTitleInfoLabel;
#pragma warning disable CS0649, IDE0044 // Field is never assigned to, Add readonly modifier
[GUI] Label _baseTitleInfoLabel;
[GUI] TextView _buildIdTextView;
[GUI] TreeView _cheatTreeView;
[GUI] Button _saveButton;
[GUI] Button _saveButton;
#pragma warning restore CS0649, IDE0044
public CheatWindow(VirtualFileSystem virtualFileSystem, ulong titleId, string titleName, string titlePath) : this(new Builder("Ryujinx.Ui.Windows.CheatWindow.glade"), virtualFileSystem, titleId, titleName, titlePath) { }
@@ -31,14 +30,14 @@ namespace Ryujinx.Ui.Windows
_baseTitleInfoLabel.Text = $"Cheats Available for {titleName} [{titleId:X16}]";
_buildIdTextView.Buffer.Text = $"BuildId: {ApplicationData.GetApplicationBuildId(virtualFileSystem, titlePath)}";
string modsBasePath = ModLoader.GetModsBasePath();
string modsBasePath = ModLoader.GetModsBasePath();
string titleModsPath = ModLoader.GetTitleDir(modsBasePath, titleId.ToString("X16"));
_enabledCheatsPath = System.IO.Path.Combine(titleModsPath, "cheats", "enabled.txt");
_cheatTreeView.Model = new TreeStore(typeof(bool), typeof(string), typeof(string), typeof(string));
CellRendererToggle enableToggle = new CellRendererToggle();
CellRendererToggle enableToggle = new();
enableToggle.Toggled += (sender, args) =>
{
_cheatTreeView.Model.GetIter(out TreeIter treeIter, new TreePath(args.Path));
@@ -62,7 +61,7 @@ namespace Ryujinx.Ui.Windows
var buildIdColumn = _cheatTreeView.AppendColumn("Build Id", new CellRendererText(), "text", 3);
buildIdColumn.Visible = false;
string[] enabled = { };
string[] enabled = Array.Empty<string>();
if (File.Exists(_enabledCheatsPath))
{
@@ -90,7 +89,7 @@ namespace Ryujinx.Ui.Windows
parentIter = ((TreeStore)_cheatTreeView.Model).AppendValues(false, buildId, parentPath, "");
}
string cleanName = cheat.Name.Substring(1, cheat.Name.Length - 8);
string cleanName = cheat.Name[1..^7];
((TreeStore)_cheatTreeView.Model).AppendValues(parentIter, enabled.Contains($"{buildId}-{cheat.Name}"), cleanName, "", buildId);
cheatAdded++;
@@ -116,7 +115,7 @@ namespace Ryujinx.Ui.Windows
return;
}
List<string> enabledCheats = new List<string>();
List<string> enabledCheats = new();
if (_cheatTreeView.Model.GetIterFirst(out TreeIter parentIter))
{

File diff suppressed because it is too large Load Diff

View File

@@ -19,16 +19,16 @@ namespace Ryujinx.Ui.Windows
{
public class DlcWindow : Window
{
private readonly VirtualFileSystem _virtualFileSystem;
private readonly string _titleId;
private readonly string _dlcJsonPath;
private readonly VirtualFileSystem _virtualFileSystem;
private readonly string _titleId;
private readonly string _dlcJsonPath;
private readonly List<DownloadableContentContainer> _dlcContainerList;
private static readonly DownloadableContentJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
private static readonly DownloadableContentJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
#pragma warning disable CS0649, IDE0044
[GUI] Label _baseTitleInfoLabel;
[GUI] TreeView _dlcTreeView;
#pragma warning disable CS0649, IDE0044 // Field is never assigned to, Add readonly modifier
[GUI] Label _baseTitleInfoLabel;
[GUI] TreeView _dlcTreeView;
[GUI] TreeSelection _dlcTreeSelection;
#pragma warning restore CS0649, IDE0044
@@ -38,23 +38,23 @@ namespace Ryujinx.Ui.Windows
{
builder.Autoconnect(this);
_titleId = titleId;
_virtualFileSystem = virtualFileSystem;
_dlcJsonPath = System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleId, "dlc.json");
_titleId = titleId;
_virtualFileSystem = virtualFileSystem;
_dlcJsonPath = System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleId, "dlc.json");
_baseTitleInfoLabel.Text = $"DLC Available for {titleName} [{titleId.ToUpper()}]";
try
{
_dlcContainerList = JsonHelper.DeserializeFromFile(_dlcJsonPath, SerializerContext.ListDownloadableContentContainer);
_dlcContainerList = JsonHelper.DeserializeFromFile(_dlcJsonPath, _serializerContext.ListDownloadableContentContainer);
}
catch
{
_dlcContainerList = new List<DownloadableContentContainer>();
}
_dlcTreeView.Model = new TreeStore(typeof(bool), typeof(string), typeof(string));
CellRendererToggle enableToggle = new CellRendererToggle();
CellRendererToggle enableToggle = new();
enableToggle.Toggled += (sender, args) =>
{
_dlcTreeView.Model.GetIter(out TreeIter treeIter, new TreePath(args.Path));
@@ -71,9 +71,9 @@ namespace Ryujinx.Ui.Windows
}
};
_dlcTreeView.AppendColumn("Enabled", enableToggle, "active", 0);
_dlcTreeView.AppendColumn("TitleId", new CellRendererText(), "text", 1);
_dlcTreeView.AppendColumn("Path", new CellRendererText(), "text", 2);
_dlcTreeView.AppendColumn("Enabled", enableToggle, "active", 0);
_dlcTreeView.AppendColumn("TitleId", new CellRendererText(), "text", 1);
_dlcTreeView.AppendColumn("Path", new CellRendererText(), "text", 2);
foreach (DownloadableContentContainer dlcContainer in _dlcContainerList)
{
@@ -85,8 +85,11 @@ namespace Ryujinx.Ui.Windows
// "enabled" box if all child NCAs are enabled. Usually fine since each nsp has only one nca.
bool areAllContentPacksEnabled = dlcContainer.DownloadableContentNcaList.TrueForAll((nca) => nca.Enabled);
TreeIter parentIter = ((TreeStore)_dlcTreeView.Model).AppendValues(areAllContentPacksEnabled, "", dlcContainer.ContainerPath);
using FileStream containerFile = File.OpenRead(dlcContainer.ContainerPath);
PartitionFileSystem pfs = new PartitionFileSystem(containerFile.AsStorage());
PartitionFileSystem pfs = new(containerFile.AsStorage());
_virtualFileSystem.ImportTickets(pfs);
foreach (DownloadableContentNca dlcNca in dlcContainer.DownloadableContentNcaList)
@@ -126,14 +129,14 @@ namespace Ryujinx.Ui.Windows
private void AddButton_Clicked(object sender, EventArgs args)
{
FileChooserNative fileChooser = new FileChooserNative("Select DLC files", this, FileChooserAction.Open, "Add", "Cancel")
FileChooserNative fileChooser = new("Select DLC files", this, FileChooserAction.Open, "Add", "Cancel")
{
SelectMultiple = true
SelectMultiple = true,
};
FileFilter filter = new FileFilter()
FileFilter filter = new()
{
Name = "Switch Game DLCs"
Name = "Switch Game DLCs",
};
filter.AddPattern("*.nsp");
@@ -148,44 +151,46 @@ namespace Ryujinx.Ui.Windows
return;
}
using (FileStream containerFile = File.OpenRead(containerPath))
using FileStream containerFile = File.OpenRead(containerPath);
PartitionFileSystem pfs = new(containerFile.AsStorage());
bool containsDlc = false;
_virtualFileSystem.ImportTickets(pfs);
TreeIter? parentIter = null;
foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
{
PartitionFileSystem pfs = new PartitionFileSystem(containerFile.AsStorage());
bool containsDlc = false;
using var ncaFile = new UniqueRef<IFile>();
_virtualFileSystem.ImportTickets(pfs);
pfs.OpenFile(ref ncaFile.Ref, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
TreeIter? parentIter = null;
Nca nca = TryCreateNca(ncaFile.Get.AsStorage(), containerPath);
foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
if (nca == null)
{
using var ncaFile = new UniqueRef<IFile>();
continue;
}
pfs.OpenFile(ref ncaFile.Ref, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
Nca nca = TryCreateNca(ncaFile.Get.AsStorage(), containerPath);
if (nca == null) continue;
if (nca.Header.ContentType == NcaContentType.PublicData)
if (nca.Header.ContentType == NcaContentType.PublicData)
{
if ((nca.Header.TitleId & 0xFFFFFFFFFFFFE000).ToString("x16") != _titleId)
{
if ((nca.Header.TitleId & 0xFFFFFFFFFFFFE000).ToString("x16") != _titleId)
{
break;
}
parentIter ??= ((TreeStore)_dlcTreeView.Model).AppendValues(true, "", containerPath);
((TreeStore)_dlcTreeView.Model).AppendValues(parentIter.Value, true, nca.Header.TitleId.ToString("X16"), fileEntry.FullPath);
containsDlc = true;
break;
}
}
if (!containsDlc)
{
GtkDialog.CreateErrorDialog("The specified file does not contain DLC for the selected title!");
parentIter ??= ((TreeStore)_dlcTreeView.Model).AppendValues(true, "", containerPath);
((TreeStore)_dlcTreeView.Model).AppendValues(parentIter.Value, true, nca.Header.TitleId.ToString("X16"), fileEntry.FullPath);
containsDlc = true;
}
}
if (!containsDlc)
{
GtkDialog.CreateErrorDialog("The specified file does not contain DLC for the selected title!");
}
}
}
@@ -206,17 +211,17 @@ namespace Ryujinx.Ui.Windows
}
}
}
private void RemoveAllButton_Clicked(object sender, EventArgs args)
{
List<TreeIter> toRemove = new List<TreeIter>();
List<TreeIter> toRemove = new();
if (_dlcTreeView.Model.GetIterFirst(out TreeIter iter))
{
do
{
toRemove.Add(iter);
}
}
while (_dlcTreeView.Model.IterNext(ref iter));
}
@@ -237,19 +242,19 @@ namespace Ryujinx.Ui.Windows
{
if (_dlcTreeView.Model.IterChildren(out TreeIter childIter, parentIter))
{
DownloadableContentContainer dlcContainer = new DownloadableContentContainer
DownloadableContentContainer dlcContainer = new()
{
ContainerPath = (string)_dlcTreeView.Model.GetValue(parentIter, 2),
DownloadableContentNcaList = new List<DownloadableContentNca>()
ContainerPath = (string)_dlcTreeView.Model.GetValue(parentIter, 2),
DownloadableContentNcaList = new List<DownloadableContentNca>(),
};
do
{
dlcContainer.DownloadableContentNcaList.Add(new DownloadableContentNca
{
Enabled = (bool)_dlcTreeView.Model.GetValue(childIter, 0),
TitleId = Convert.ToUInt64(_dlcTreeView.Model.GetValue(childIter, 1).ToString(), 16),
FullPath = (string)_dlcTreeView.Model.GetValue(childIter, 2)
Enabled = (bool)_dlcTreeView.Model.GetValue(childIter, 0),
TitleId = Convert.ToUInt64(_dlcTreeView.Model.GetValue(childIter, 1).ToString(), 16),
FullPath = (string)_dlcTreeView.Model.GetValue(childIter, 2),
});
}
while (_dlcTreeView.Model.IterNext(ref childIter));
@@ -260,7 +265,7 @@ namespace Ryujinx.Ui.Windows
while (_dlcTreeView.Model.IterNext(ref parentIter));
}
JsonHelper.SerializeToFile(_dlcJsonPath, _dlcContainerList, SerializerContext.ListDownloadableContentContainer);
JsonHelper.SerializeToFile(_dlcJsonPath, _dlcContainerList, _serializerContext.ListDownloadableContentContainer);
Dispose();
}

View File

@@ -6,14 +6,12 @@ using Ryujinx.Audio.Backends.SoundIo;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.GraphicsDriver;
using Ryujinx.Graphics.Vulkan;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Time.TimeZone;
using Ryujinx.Ui.Common.Configuration;
using Ryujinx.Ui.Common.Configuration.System;
using Ryujinx.Ui.Helper;
using Ryujinx.Ui.Widgets;
using Silk.NET.Vulkan;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -27,95 +25,95 @@ namespace Ryujinx.Ui.Windows
{
public class SettingsWindow : Window
{
private readonly MainWindow _parent;
private readonly ListStore _gameDirsBoxStore;
private readonly ListStore _audioBackendStore;
private readonly MainWindow _parent;
private readonly ListStore _gameDirsBoxStore;
private readonly ListStore _audioBackendStore;
private readonly TimeZoneContentManager _timeZoneContentManager;
private readonly HashSet<string> _validTzRegions;
private readonly HashSet<string> _validTzRegions;
private long _systemTimeOffset;
private long _systemTimeOffset;
private float _previousVolumeLevel;
private bool _directoryChanged = false;
#pragma warning disable CS0649, IDE0044
[GUI] CheckButton _traceLogToggle;
[GUI] CheckButton _errorLogToggle;
[GUI] CheckButton _warningLogToggle;
[GUI] CheckButton _infoLogToggle;
[GUI] CheckButton _stubLogToggle;
[GUI] CheckButton _debugLogToggle;
[GUI] CheckButton _fileLogToggle;
[GUI] CheckButton _guestLogToggle;
[GUI] CheckButton _fsAccessLogToggle;
[GUI] Adjustment _fsLogSpinAdjustment;
[GUI] ComboBoxText _graphicsDebugLevel;
[GUI] CheckButton _dockedModeToggle;
[GUI] CheckButton _discordToggle;
[GUI] CheckButton _checkUpdatesToggle;
[GUI] CheckButton _showConfirmExitToggle;
[GUI] RadioButton _hideCursorNever;
[GUI] RadioButton _hideCursorOnIdle;
[GUI] RadioButton _hideCursorAlways;
[GUI] CheckButton _vSyncToggle;
[GUI] CheckButton _shaderCacheToggle;
[GUI] CheckButton _textureRecompressionToggle;
[GUI] CheckButton _macroHLEToggle;
[GUI] CheckButton _ptcToggle;
[GUI] CheckButton _internetToggle;
[GUI] CheckButton _fsicToggle;
[GUI] RadioButton _mmSoftware;
[GUI] RadioButton _mmHost;
[GUI] RadioButton _mmHostUnsafe;
[GUI] CheckButton _expandRamToggle;
[GUI] CheckButton _ignoreToggle;
[GUI] CheckButton _directKeyboardAccess;
[GUI] CheckButton _directMouseAccess;
[GUI] ComboBoxText _systemLanguageSelect;
[GUI] ComboBoxText _systemRegionSelect;
[GUI] Entry _systemTimeZoneEntry;
#pragma warning disable CS0649, IDE0044 // Field is never assigned to, Add readonly modifier
[GUI] CheckButton _traceLogToggle;
[GUI] CheckButton _errorLogToggle;
[GUI] CheckButton _warningLogToggle;
[GUI] CheckButton _infoLogToggle;
[GUI] CheckButton _stubLogToggle;
[GUI] CheckButton _debugLogToggle;
[GUI] CheckButton _fileLogToggle;
[GUI] CheckButton _guestLogToggle;
[GUI] CheckButton _fsAccessLogToggle;
[GUI] Adjustment _fsLogSpinAdjustment;
[GUI] ComboBoxText _graphicsDebugLevel;
[GUI] CheckButton _dockedModeToggle;
[GUI] CheckButton _discordToggle;
[GUI] CheckButton _checkUpdatesToggle;
[GUI] CheckButton _showConfirmExitToggle;
[GUI] RadioButton _hideCursorNever;
[GUI] RadioButton _hideCursorOnIdle;
[GUI] RadioButton _hideCursorAlways;
[GUI] CheckButton _vSyncToggle;
[GUI] CheckButton _shaderCacheToggle;
[GUI] CheckButton _textureRecompressionToggle;
[GUI] CheckButton _macroHLEToggle;
[GUI] CheckButton _ptcToggle;
[GUI] CheckButton _internetToggle;
[GUI] CheckButton _fsicToggle;
[GUI] RadioButton _mmSoftware;
[GUI] RadioButton _mmHost;
[GUI] RadioButton _mmHostUnsafe;
[GUI] CheckButton _expandRamToggle;
[GUI] CheckButton _ignoreToggle;
[GUI] CheckButton _directKeyboardAccess;
[GUI] CheckButton _directMouseAccess;
[GUI] ComboBoxText _systemLanguageSelect;
[GUI] ComboBoxText _systemRegionSelect;
[GUI] Entry _systemTimeZoneEntry;
[GUI] EntryCompletion _systemTimeZoneCompletion;
[GUI] Box _audioBackendBox;
[GUI] ComboBox _audioBackendSelect;
[GUI] Label _audioVolumeLabel;
[GUI] Scale _audioVolumeSlider;
[GUI] SpinButton _systemTimeYearSpin;
[GUI] SpinButton _systemTimeMonthSpin;
[GUI] SpinButton _systemTimeDaySpin;
[GUI] SpinButton _systemTimeHourSpin;
[GUI] SpinButton _systemTimeMinuteSpin;
[GUI] Adjustment _systemTimeYearSpinAdjustment;
[GUI] Adjustment _systemTimeMonthSpinAdjustment;
[GUI] Adjustment _systemTimeDaySpinAdjustment;
[GUI] Adjustment _systemTimeHourSpinAdjustment;
[GUI] Adjustment _systemTimeMinuteSpinAdjustment;
[GUI] ComboBoxText _multiLanSelect;
[GUI] CheckButton _custThemeToggle;
[GUI] Entry _custThemePath;
[GUI] ToggleButton _browseThemePath;
[GUI] Label _custThemePathLabel;
[GUI] TreeView _gameDirsBox;
[GUI] Entry _addGameDirBox;
[GUI] ComboBoxText _galThreading;
[GUI] Entry _graphicsShadersDumpPath;
[GUI] ComboBoxText _anisotropy;
[GUI] ComboBoxText _aspectRatio;
[GUI] ComboBoxText _antiAliasing;
[GUI] ComboBoxText _scalingFilter;
[GUI] ComboBoxText _graphicsBackend;
[GUI] ComboBoxText _preferredGpu;
[GUI] ComboBoxText _resScaleCombo;
[GUI] Entry _resScaleText;
[GUI] Adjustment _scalingFilterLevel;
[GUI] Scale _scalingFilterSlider;
[GUI] ToggleButton _configureController1;
[GUI] ToggleButton _configureController2;
[GUI] ToggleButton _configureController3;
[GUI] ToggleButton _configureController4;
[GUI] ToggleButton _configureController5;
[GUI] ToggleButton _configureController6;
[GUI] ToggleButton _configureController7;
[GUI] ToggleButton _configureController8;
[GUI] ToggleButton _configureControllerH;
[GUI] Box _audioBackendBox;
[GUI] ComboBox _audioBackendSelect;
[GUI] Label _audioVolumeLabel;
[GUI] Scale _audioVolumeSlider;
[GUI] SpinButton _systemTimeYearSpin;
[GUI] SpinButton _systemTimeMonthSpin;
[GUI] SpinButton _systemTimeDaySpin;
[GUI] SpinButton _systemTimeHourSpin;
[GUI] SpinButton _systemTimeMinuteSpin;
[GUI] Adjustment _systemTimeYearSpinAdjustment;
[GUI] Adjustment _systemTimeMonthSpinAdjustment;
[GUI] Adjustment _systemTimeDaySpinAdjustment;
[GUI] Adjustment _systemTimeHourSpinAdjustment;
[GUI] Adjustment _systemTimeMinuteSpinAdjustment;
[GUI] ComboBoxText _multiLanSelect;
[GUI] CheckButton _custThemeToggle;
[GUI] Entry _custThemePath;
[GUI] ToggleButton _browseThemePath;
[GUI] Label _custThemePathLabel;
[GUI] TreeView _gameDirsBox;
[GUI] Entry _addGameDirBox;
[GUI] ComboBoxText _galThreading;
[GUI] Entry _graphicsShadersDumpPath;
[GUI] ComboBoxText _anisotropy;
[GUI] ComboBoxText _aspectRatio;
[GUI] ComboBoxText _antiAliasing;
[GUI] ComboBoxText _scalingFilter;
[GUI] ComboBoxText _graphicsBackend;
[GUI] ComboBoxText _preferredGpu;
[GUI] ComboBoxText _resScaleCombo;
[GUI] Entry _resScaleText;
[GUI] Adjustment _scalingFilterLevel;
[GUI] Scale _scalingFilterSlider;
[GUI] ToggleButton _configureController1;
[GUI] ToggleButton _configureController2;
[GUI] ToggleButton _configureController3;
[GUI] ToggleButton _configureController4;
[GUI] ToggleButton _configureController5;
[GUI] ToggleButton _configureController6;
[GUI] ToggleButton _configureController7;
[GUI] ToggleButton _configureController8;
[GUI] ToggleButton _configureControllerH;
#pragma warning restore CS0649, IDE0044
@@ -316,11 +314,11 @@ namespace Ryujinx.Ui.Windows
}
// Custom EntryCompletion Columns. If added to glade, need to override more signals
ListStore tzList = new ListStore(typeof(string), typeof(string), typeof(string));
ListStore tzList = new(typeof(string), typeof(string), typeof(string));
_systemTimeZoneCompletion.Model = tzList;
CellRendererText offsetCol = new CellRendererText();
CellRendererText abbrevCol = new CellRendererText();
CellRendererText offsetCol = new();
CellRendererText abbrevCol = new();
_systemTimeZoneCompletion.PackStart(offsetCol, false);
_systemTimeZoneCompletion.AddAttribute(offsetCol, "text", 0);
@@ -364,17 +362,17 @@ namespace Ryujinx.Ui.Windows
PopulateNetworkInterfaces();
_multiLanSelect.SetActiveId(ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value);
_custThemePath.Buffer.Text = ConfigurationState.Instance.Ui.CustomThemePath;
_resScaleText.Buffer.Text = ConfigurationState.Instance.Graphics.ResScaleCustom.Value.ToString();
_scalingFilterLevel.Value = ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value;
_resScaleText.Visible = _resScaleCombo.ActiveId == "-1";
_scalingFilterSlider.Visible = _scalingFilter.ActiveId == "2";
_custThemePath.Buffer.Text = ConfigurationState.Instance.Ui.CustomThemePath;
_resScaleText.Buffer.Text = ConfigurationState.Instance.Graphics.ResScaleCustom.Value.ToString();
_scalingFilterLevel.Value = ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value;
_resScaleText.Visible = _resScaleCombo.ActiveId == "-1";
_scalingFilterSlider.Visible = _scalingFilter.ActiveId == "2";
_graphicsShadersDumpPath.Buffer.Text = ConfigurationState.Instance.Graphics.ShadersDumpPath;
_fsLogSpinAdjustment.Value = ConfigurationState.Instance.System.FsGlobalAccessLogMode;
_systemTimeOffset = ConfigurationState.Instance.System.SystemTimeOffset;
_fsLogSpinAdjustment.Value = ConfigurationState.Instance.System.FsGlobalAccessLogMode;
_systemTimeOffset = ConfigurationState.Instance.System.SystemTimeOffset;
_gameDirsBox.AppendColumn("", new CellRendererText(), "text", 0);
_gameDirsBoxStore = new ListStore(typeof(string));
_gameDirsBoxStore = new ListStore(typeof(string));
_gameDirsBox.Model = _gameDirsBoxStore;
foreach (string gameDir in ConfigurationState.Instance.Ui.GameDirs.Value)
@@ -384,9 +382,9 @@ namespace Ryujinx.Ui.Windows
if (_custThemeToggle.Active == false)
{
_custThemePath.Sensitive = false;
_custThemePath.Sensitive = false;
_custThemePathLabel.Sensitive = false;
_browseThemePath.Sensitive = false;
_browseThemePath.Sensitive = false;
}
// Setup system time spinners
@@ -394,10 +392,10 @@ namespace Ryujinx.Ui.Windows
_audioBackendStore = new ListStore(typeof(string), typeof(AudioBackend));
TreeIter openAlIter = _audioBackendStore.AppendValues("OpenAL", AudioBackend.OpenAl);
TreeIter openAlIter = _audioBackendStore.AppendValues("OpenAL", AudioBackend.OpenAl);
TreeIter soundIoIter = _audioBackendStore.AppendValues("SoundIO", AudioBackend.SoundIo);
TreeIter sdl2Iter = _audioBackendStore.AppendValues("SDL2", AudioBackend.SDL2);
TreeIter dummyIter = _audioBackendStore.AppendValues("Dummy", AudioBackend.Dummy);
TreeIter sdl2Iter = _audioBackendStore.AppendValues("SDL2", AudioBackend.SDL2);
TreeIter dummyIter = _audioBackendStore.AppendValues("Dummy", AudioBackend.Dummy);
_audioBackendSelect = ComboBox.NewWithModelAndEntry(_audioBackendStore);
_audioBackendSelect.EntryTextColumn = 0;
@@ -418,35 +416,35 @@ namespace Ryujinx.Ui.Windows
_audioBackendSelect.SetActiveIter(dummyIter);
break;
default:
throw new ArgumentOutOfRangeException();
throw new InvalidOperationException($"{nameof(ConfigurationState.Instance.System.AudioBackend)} contains an invalid value: {ConfigurationState.Instance.System.AudioBackend.Value}");
}
_audioBackendBox.Add(_audioBackendSelect);
_audioBackendSelect.Show();
_previousVolumeLevel = ConfigurationState.Instance.System.AudioVolume;
_audioVolumeLabel = new Label("Volume: ");
_audioVolumeSlider = new Scale(Orientation.Horizontal, 0, 100, 1);
_audioVolumeLabel.MarginStart = 10;
_audioVolumeSlider.ValuePos = PositionType.Right;
_previousVolumeLevel = ConfigurationState.Instance.System.AudioVolume;
_audioVolumeLabel = new Label("Volume: ");
_audioVolumeSlider = new Scale(Orientation.Horizontal, 0, 100, 1);
_audioVolumeLabel.MarginStart = 10;
_audioVolumeSlider.ValuePos = PositionType.Right;
_audioVolumeSlider.WidthRequest = 200;
_audioVolumeSlider.Value = _previousVolumeLevel * 100;
_audioVolumeSlider.Value = _previousVolumeLevel * 100;
_audioVolumeSlider.ValueChanged += VolumeSlider_OnChange;
_audioBackendBox.Add(_audioVolumeLabel);
_audioBackendBox.Add(_audioVolumeSlider);
_audioVolumeLabel.Show();
_audioVolumeSlider.Show();
bool openAlIsSupported = false;
bool openAlIsSupported = false;
bool soundIoIsSupported = false;
bool sdl2IsSupported = false;
bool sdl2IsSupported = false;
Task.Run(() =>
{
openAlIsSupported = OpenALHardwareDeviceDriver.IsSupported;
openAlIsSupported = OpenALHardwareDeviceDriver.IsSupported;
soundIoIsSupported = !OperatingSystem.IsMacOS() && SoundIoHardwareDeviceDriver.IsSupported;
sdl2IsSupported = SDL2HardwareDeviceDriver.IsSupported;
sdl2IsSupported = SDL2HardwareDeviceDriver.IsSupported;
});
// This function runs whenever the dropdown is opened
@@ -454,18 +452,18 @@ namespace Ryujinx.Ui.Windows
{
cell.Sensitive = ((AudioBackend)_audioBackendStore.GetValue(iter, 1)) switch
{
AudioBackend.OpenAl => openAlIsSupported,
AudioBackend.OpenAl => openAlIsSupported,
AudioBackend.SoundIo => soundIoIsSupported,
AudioBackend.SDL2 => sdl2IsSupported,
AudioBackend.Dummy => true,
_ => throw new ArgumentOutOfRangeException()
AudioBackend.SDL2 => sdl2IsSupported,
AudioBackend.Dummy => true,
_ => throw new InvalidOperationException($"{nameof(_audioBackendStore)} contains an invalid value for iteration {iter}: {_audioBackendStore.GetValue(iter, 1)}"),
};
});
if (OperatingSystem.IsMacOS())
{
var store = (_graphicsBackend.Model as ListStore);
store.GetIter(out TreeIter openglIter, new TreePath(new int[] {1}));
store.GetIter(out TreeIter openglIter, new TreePath(new[] { 1 }));
store.Remove(ref openglIter);
_graphicsBackend.Model = store;
@@ -478,15 +476,15 @@ namespace Ryujinx.Ui.Windows
if (Enum.Parse<GraphicsBackend>(_graphicsBackend.ActiveId) == GraphicsBackend.Vulkan)
{
var devices = VulkanRenderer.GetPhysicalDevices();
var devices = Graphics.Vulkan.VulkanRenderer.GetPhysicalDevices();
string preferredGpuIdFromConfig = ConfigurationState.Instance.Graphics.PreferredGpu.Value;
string preferredGpuId = preferredGpuIdFromConfig;
bool noGpuId = string.IsNullOrEmpty(preferredGpuIdFromConfig);
foreach (var device in devices)
{
string dGPU = device.IsDiscrete ? " (dGPU)" : "";
_preferredGpu.Append(device.Id, $"{device.Name}{dGPU}");
string dGpu = device.IsDiscrete ? " (dGPU)" : "";
_preferredGpu.Append(device.Id, $"{device.Name}{dGpu}");
// If there's no GPU selected yet, we just pick the first GPU.
// If there's a discrete GPU available, we always prefer that over the previous selection,
@@ -521,33 +519,33 @@ namespace Ryujinx.Ui.Windows
private void UpdateSystemTimeSpinners()
{
//Bind system time events
_systemTimeYearSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
_systemTimeMonthSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
_systemTimeDaySpin.ValueChanged -= SystemTimeSpin_ValueChanged;
_systemTimeHourSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
_systemTimeYearSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
_systemTimeMonthSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
_systemTimeDaySpin.ValueChanged -= SystemTimeSpin_ValueChanged;
_systemTimeHourSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
_systemTimeMinuteSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
//Apply actual system time + SystemTimeOffset to system time spin buttons
DateTime systemTime = DateTime.Now.AddSeconds(_systemTimeOffset);
_systemTimeYearSpinAdjustment.Value = systemTime.Year;
_systemTimeMonthSpinAdjustment.Value = systemTime.Month;
_systemTimeDaySpinAdjustment.Value = systemTime.Day;
_systemTimeHourSpinAdjustment.Value = systemTime.Hour;
_systemTimeYearSpinAdjustment.Value = systemTime.Year;
_systemTimeMonthSpinAdjustment.Value = systemTime.Month;
_systemTimeDaySpinAdjustment.Value = systemTime.Day;
_systemTimeHourSpinAdjustment.Value = systemTime.Hour;
_systemTimeMinuteSpinAdjustment.Value = systemTime.Minute;
//Format spin buttons text to include leading zeros
_systemTimeYearSpin.Text = systemTime.Year.ToString("0000");
_systemTimeMonthSpin.Text = systemTime.Month.ToString("00");
_systemTimeDaySpin.Text = systemTime.Day.ToString("00");
_systemTimeHourSpin.Text = systemTime.Hour.ToString("00");
_systemTimeYearSpin.Text = systemTime.Year.ToString("0000");
_systemTimeMonthSpin.Text = systemTime.Month.ToString("00");
_systemTimeDaySpin.Text = systemTime.Day.ToString("00");
_systemTimeHourSpin.Text = systemTime.Hour.ToString("00");
_systemTimeMinuteSpin.Text = systemTime.Minute.ToString("00");
//Bind system time events
_systemTimeYearSpin.ValueChanged += SystemTimeSpin_ValueChanged;
_systemTimeMonthSpin.ValueChanged += SystemTimeSpin_ValueChanged;
_systemTimeDaySpin.ValueChanged += SystemTimeSpin_ValueChanged;
_systemTimeHourSpin.ValueChanged += SystemTimeSpin_ValueChanged;
_systemTimeYearSpin.ValueChanged += SystemTimeSpin_ValueChanged;
_systemTimeMonthSpin.ValueChanged += SystemTimeSpin_ValueChanged;
_systemTimeDaySpin.ValueChanged += SystemTimeSpin_ValueChanged;
_systemTimeHourSpin.ValueChanged += SystemTimeSpin_ValueChanged;
_systemTimeMinuteSpin.ValueChanged += SystemTimeSpin_ValueChanged;
}
@@ -555,7 +553,7 @@ namespace Ryujinx.Ui.Windows
{
if (_directoryChanged)
{
List<string> gameDirs = new List<string>();
List<string> gameDirs = new();
_gameDirsBoxStore.GetIterFirst(out TreeIter treeIter);
@@ -611,52 +609,52 @@ namespace Ryujinx.Ui.Windows
DriverUtilities.ToggleOGLThreading(backendThreading == BackendThreading.Off);
}
ConfigurationState.Instance.Logger.EnableError.Value = _errorLogToggle.Active;
ConfigurationState.Instance.Logger.EnableTrace.Value = _traceLogToggle.Active;
ConfigurationState.Instance.Logger.EnableWarn.Value = _warningLogToggle.Active;
ConfigurationState.Instance.Logger.EnableInfo.Value = _infoLogToggle.Active;
ConfigurationState.Instance.Logger.EnableStub.Value = _stubLogToggle.Active;
ConfigurationState.Instance.Logger.EnableDebug.Value = _debugLogToggle.Active;
ConfigurationState.Instance.Logger.EnableGuest.Value = _guestLogToggle.Active;
ConfigurationState.Instance.Logger.EnableFsAccessLog.Value = _fsAccessLogToggle.Active;
ConfigurationState.Instance.Logger.EnableFileLog.Value = _fileLogToggle.Active;
ConfigurationState.Instance.Logger.GraphicsDebugLevel.Value = Enum.Parse<GraphicsDebugLevel>(_graphicsDebugLevel.ActiveId);
ConfigurationState.Instance.System.EnableDockedMode.Value = _dockedModeToggle.Active;
ConfigurationState.Instance.EnableDiscordIntegration.Value = _discordToggle.Active;
ConfigurationState.Instance.CheckUpdatesOnStart.Value = _checkUpdatesToggle.Active;
ConfigurationState.Instance.ShowConfirmExit.Value = _showConfirmExitToggle.Active;
ConfigurationState.Instance.HideCursor.Value = hideCursor;
ConfigurationState.Instance.Graphics.EnableVsync.Value = _vSyncToggle.Active;
ConfigurationState.Instance.Graphics.EnableShaderCache.Value = _shaderCacheToggle.Active;
ConfigurationState.Instance.Logger.EnableError.Value = _errorLogToggle.Active;
ConfigurationState.Instance.Logger.EnableTrace.Value = _traceLogToggle.Active;
ConfigurationState.Instance.Logger.EnableWarn.Value = _warningLogToggle.Active;
ConfigurationState.Instance.Logger.EnableInfo.Value = _infoLogToggle.Active;
ConfigurationState.Instance.Logger.EnableStub.Value = _stubLogToggle.Active;
ConfigurationState.Instance.Logger.EnableDebug.Value = _debugLogToggle.Active;
ConfigurationState.Instance.Logger.EnableGuest.Value = _guestLogToggle.Active;
ConfigurationState.Instance.Logger.EnableFsAccessLog.Value = _fsAccessLogToggle.Active;
ConfigurationState.Instance.Logger.EnableFileLog.Value = _fileLogToggle.Active;
ConfigurationState.Instance.Logger.GraphicsDebugLevel.Value = Enum.Parse<GraphicsDebugLevel>(_graphicsDebugLevel.ActiveId);
ConfigurationState.Instance.System.EnableDockedMode.Value = _dockedModeToggle.Active;
ConfigurationState.Instance.EnableDiscordIntegration.Value = _discordToggle.Active;
ConfigurationState.Instance.CheckUpdatesOnStart.Value = _checkUpdatesToggle.Active;
ConfigurationState.Instance.ShowConfirmExit.Value = _showConfirmExitToggle.Active;
ConfigurationState.Instance.HideCursor.Value = hideCursor;
ConfigurationState.Instance.Graphics.EnableVsync.Value = _vSyncToggle.Active;
ConfigurationState.Instance.Graphics.EnableShaderCache.Value = _shaderCacheToggle.Active;
ConfigurationState.Instance.Graphics.EnableTextureRecompression.Value = _textureRecompressionToggle.Active;
ConfigurationState.Instance.Graphics.EnableMacroHLE.Value = _macroHLEToggle.Active;
ConfigurationState.Instance.System.EnablePtc.Value = _ptcToggle.Active;
ConfigurationState.Instance.System.EnableInternetAccess.Value = _internetToggle.Active;
ConfigurationState.Instance.System.EnableFsIntegrityChecks.Value = _fsicToggle.Active;
ConfigurationState.Instance.System.MemoryManagerMode.Value = memoryMode;
ConfigurationState.Instance.System.ExpandRam.Value = _expandRamToggle.Active;
ConfigurationState.Instance.System.IgnoreMissingServices.Value = _ignoreToggle.Active;
ConfigurationState.Instance.Hid.EnableKeyboard.Value = _directKeyboardAccess.Active;
ConfigurationState.Instance.Hid.EnableMouse.Value = _directMouseAccess.Active;
ConfigurationState.Instance.Ui.EnableCustomTheme.Value = _custThemeToggle.Active;
ConfigurationState.Instance.System.Language.Value = Enum.Parse<Language>(_systemLanguageSelect.ActiveId);
ConfigurationState.Instance.System.Region.Value = Enum.Parse<Common.Configuration.System.Region>(_systemRegionSelect.ActiveId);
ConfigurationState.Instance.System.SystemTimeOffset.Value = _systemTimeOffset;
ConfigurationState.Instance.Ui.CustomThemePath.Value = _custThemePath.Buffer.Text;
ConfigurationState.Instance.Graphics.ShadersDumpPath.Value = _graphicsShadersDumpPath.Buffer.Text;
ConfigurationState.Instance.System.FsGlobalAccessLogMode.Value = (int)_fsLogSpinAdjustment.Value;
ConfigurationState.Instance.Graphics.MaxAnisotropy.Value = float.Parse(_anisotropy.ActiveId, CultureInfo.InvariantCulture);
ConfigurationState.Instance.Graphics.AspectRatio.Value = Enum.Parse<AspectRatio>(_aspectRatio.ActiveId);
ConfigurationState.Instance.Graphics.BackendThreading.Value = backendThreading;
ConfigurationState.Instance.Graphics.GraphicsBackend.Value = Enum.Parse<GraphicsBackend>(_graphicsBackend.ActiveId);
ConfigurationState.Instance.Graphics.PreferredGpu.Value = _preferredGpu.ActiveId;
ConfigurationState.Instance.Graphics.ResScale.Value = int.Parse(_resScaleCombo.ActiveId);
ConfigurationState.Instance.Graphics.ResScaleCustom.Value = resScaleCustom;
ConfigurationState.Instance.System.AudioVolume.Value = (float)_audioVolumeSlider.Value / 100.0f;
ConfigurationState.Instance.Graphics.AntiAliasing.Value = Enum.Parse<AntiAliasing>(_antiAliasing.ActiveId);
ConfigurationState.Instance.Graphics.ScalingFilter.Value = Enum.Parse<ScalingFilter>(_scalingFilter.ActiveId);
ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value = (int)_scalingFilterLevel.Value;
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value = _multiLanSelect.ActiveId;
ConfigurationState.Instance.Graphics.EnableMacroHLE.Value = _macroHLEToggle.Active;
ConfigurationState.Instance.System.EnablePtc.Value = _ptcToggle.Active;
ConfigurationState.Instance.System.EnableInternetAccess.Value = _internetToggle.Active;
ConfigurationState.Instance.System.EnableFsIntegrityChecks.Value = _fsicToggle.Active;
ConfigurationState.Instance.System.MemoryManagerMode.Value = memoryMode;
ConfigurationState.Instance.System.ExpandRam.Value = _expandRamToggle.Active;
ConfigurationState.Instance.System.IgnoreMissingServices.Value = _ignoreToggle.Active;
ConfigurationState.Instance.Hid.EnableKeyboard.Value = _directKeyboardAccess.Active;
ConfigurationState.Instance.Hid.EnableMouse.Value = _directMouseAccess.Active;
ConfigurationState.Instance.Ui.EnableCustomTheme.Value = _custThemeToggle.Active;
ConfigurationState.Instance.System.Language.Value = Enum.Parse<Language>(_systemLanguageSelect.ActiveId);
ConfigurationState.Instance.System.Region.Value = Enum.Parse<Common.Configuration.System.Region>(_systemRegionSelect.ActiveId);
ConfigurationState.Instance.System.SystemTimeOffset.Value = _systemTimeOffset;
ConfigurationState.Instance.Ui.CustomThemePath.Value = _custThemePath.Buffer.Text;
ConfigurationState.Instance.Graphics.ShadersDumpPath.Value = _graphicsShadersDumpPath.Buffer.Text;
ConfigurationState.Instance.System.FsGlobalAccessLogMode.Value = (int)_fsLogSpinAdjustment.Value;
ConfigurationState.Instance.Graphics.MaxAnisotropy.Value = float.Parse(_anisotropy.ActiveId, CultureInfo.InvariantCulture);
ConfigurationState.Instance.Graphics.AspectRatio.Value = Enum.Parse<AspectRatio>(_aspectRatio.ActiveId);
ConfigurationState.Instance.Graphics.BackendThreading.Value = backendThreading;
ConfigurationState.Instance.Graphics.GraphicsBackend.Value = Enum.Parse<GraphicsBackend>(_graphicsBackend.ActiveId);
ConfigurationState.Instance.Graphics.PreferredGpu.Value = _preferredGpu.ActiveId;
ConfigurationState.Instance.Graphics.ResScale.Value = int.Parse(_resScaleCombo.ActiveId);
ConfigurationState.Instance.Graphics.ResScaleCustom.Value = resScaleCustom;
ConfigurationState.Instance.System.AudioVolume.Value = (float)_audioVolumeSlider.Value / 100.0f;
ConfigurationState.Instance.Graphics.AntiAliasing.Value = Enum.Parse<AntiAliasing>(_antiAliasing.ActiveId);
ConfigurationState.Instance.Graphics.ScalingFilter.Value = Enum.Parse<ScalingFilter>(_scalingFilter.ActiveId);
ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value = (int)_scalingFilterLevel.Value;
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value = _multiLanSelect.ActiveId;
_previousVolumeLevel = ConfigurationState.Instance.System.AudioVolume.Value;
@@ -666,7 +664,7 @@ namespace Ryujinx.Ui.Windows
}
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
_parent.UpdateGraphicsConfig();
MainWindow.UpdateGraphicsConfig();
ThemeHelper.ApplyTheme();
}
@@ -692,10 +690,10 @@ namespace Ryujinx.Ui.Windows
private void SystemTimeSpin_ValueChanged(object sender, EventArgs e)
{
int year = _systemTimeYearSpin.ValueAsInt;
int month = _systemTimeMonthSpin.ValueAsInt;
int day = _systemTimeDaySpin.ValueAsInt;
int hour = _systemTimeHourSpin.ValueAsInt;
int year = _systemTimeYearSpin.ValueAsInt;
int month = _systemTimeMonthSpin.ValueAsInt;
int day = _systemTimeDaySpin.ValueAsInt;
int hour = _systemTimeHourSpin.ValueAsInt;
int minute = _systemTimeMinuteSpin.ValueAsInt;
if (!DateTime.TryParse(year + "-" + month + "-" + day + " " + hour + ":" + minute, out DateTime newTime))
@@ -725,9 +723,9 @@ namespace Ryujinx.Ui.Windows
}
else
{
FileChooserNative fileChooser = new FileChooserNative("Choose the game directory to add to the list", this, FileChooserAction.SelectFolder, "Add", "Cancel")
FileChooserNative fileChooser = new("Choose the game directory to add to the list", this, FileChooserAction.SelectFolder, "Add", "Cancel")
{
SelectMultiple = true
SelectMultiple = true,
};
if (fileChooser.Run() == (int)ResponseType.Accept)
@@ -779,18 +777,18 @@ namespace Ryujinx.Ui.Windows
private void CustThemeToggle_Activated(object sender, EventArgs args)
{
_custThemePath.Sensitive = _custThemeToggle.Active;
_custThemePath.Sensitive = _custThemeToggle.Active;
_custThemePathLabel.Sensitive = _custThemeToggle.Active;
_browseThemePath.Sensitive = _custThemeToggle.Active;
_browseThemePath.Sensitive = _custThemeToggle.Active;
}
private void BrowseThemeDir_Pressed(object sender, EventArgs args)
{
using (FileChooserNative fileChooser = new FileChooserNative("Choose the theme to load", this, FileChooserAction.Open, "Select", "Cancel"))
using (FileChooserNative fileChooser = new("Choose the theme to load", this, FileChooserAction.Open, "Select", "Cancel"))
{
FileFilter filter = new FileFilter()
FileFilter filter = new()
{
Name = "Theme Files"
Name = "Theme Files",
};
filter.AddPattern("*.css");
@@ -809,7 +807,7 @@ namespace Ryujinx.Ui.Windows
{
((ToggleButton)sender).SetStateFlags(StateFlags.Normal, true);
ControllerWindow controllerWindow = new ControllerWindow(_parent, playerIndex);
ControllerWindow controllerWindow = new(_parent, playerIndex);
controllerWindow.SetSizeRequest((int)(controllerWindow.DefaultWidth * Program.WindowScaleFactor), (int)(controllerWindow.DefaultHeight * Program.WindowScaleFactor));
controllerWindow.Show();

View File

@@ -9,33 +9,32 @@ using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Utilities;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS;
using Ryujinx.Ui.App.Common;
using Ryujinx.Ui.Widgets;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using GUI = Gtk.Builder.ObjectAttribute;
using GUI = Gtk.Builder.ObjectAttribute;
using SpanHelpers = LibHac.Common.SpanHelpers;
namespace Ryujinx.Ui.Windows
{
public class TitleUpdateWindow : Window
{
private readonly MainWindow _parent;
private readonly MainWindow _parent;
private readonly VirtualFileSystem _virtualFileSystem;
private readonly string _titleId;
private readonly string _updateJsonPath;
private readonly string _titleId;
private readonly string _updateJsonPath;
private TitleUpdateMetadata _titleUpdateWindowData;
private readonly Dictionary<RadioButton, string> _radioButtonToPathDictionary;
private static readonly TitleUpdateMetadataJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
private static readonly TitleUpdateMetadataJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
#pragma warning disable CS0649, IDE0044
[GUI] Label _baseTitleInfoLabel;
[GUI] Box _availableUpdatesBox;
#pragma warning disable CS0649, IDE0044 // Field is never assigned to, Add readonly modifier
[GUI] Label _baseTitleInfoLabel;
[GUI] Box _availableUpdatesBox;
[GUI] RadioButton _noUpdateRadioButton;
#pragma warning restore CS0649, IDE0044
@@ -47,26 +46,26 @@ namespace Ryujinx.Ui.Windows
builder.Autoconnect(this);
_titleId = titleId;
_virtualFileSystem = virtualFileSystem;
_updateJsonPath = System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleId, "updates.json");
_titleId = titleId;
_virtualFileSystem = virtualFileSystem;
_updateJsonPath = System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleId, "updates.json");
_radioButtonToPathDictionary = new Dictionary<RadioButton, string>();
try
{
_titleUpdateWindowData = JsonHelper.DeserializeFromFile(_updateJsonPath, SerializerContext.TitleUpdateMetadata);
_titleUpdateWindowData = JsonHelper.DeserializeFromFile(_updateJsonPath, _serializerContext.TitleUpdateMetadata);
}
catch
{
_titleUpdateWindowData = new TitleUpdateMetadata
{
Selected = "",
Paths = new List<string>()
Paths = new List<string>(),
};
}
_baseTitleInfoLabel.Text = $"Updates Available for {titleName} [{titleId.ToUpper()}]";
foreach (string path in _titleUpdateWindowData.Paths)
{
AddUpdate(path);
@@ -89,42 +88,41 @@ namespace Ryujinx.Ui.Windows
{
if (File.Exists(path))
{
using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read))
using FileStream file = new(path, FileMode.Open, FileAccess.Read);
PartitionFileSystem nsp = new(file.AsStorage());
try
{
PartitionFileSystem nsp = new PartitionFileSystem(file.AsStorage());
(Nca patchNca, Nca controlNca) = ApplicationLibrary.GetGameUpdateDataFromPartition(_virtualFileSystem, nsp, _titleId, 0);
try
if (controlNca != null && patchNca != null)
{
(Nca patchNca, Nca controlNca) = ApplicationLibrary.GetGameUpdateDataFromPartition(_virtualFileSystem, nsp, _titleId, 0);
ApplicationControlProperty controlData = new();
if (controlNca != null && patchNca != null)
{
ApplicationControlProperty controlData = new ApplicationControlProperty();
using var nacpFile = new UniqueRef<IFile>();
using var nacpFile = new UniqueRef<IFile>();
controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
RadioButton radioButton = new($"Version {controlData.DisplayVersionString.ToString()} - {path}");
radioButton.JoinGroup(_noUpdateRadioButton);
RadioButton radioButton = new RadioButton($"Version {controlData.DisplayVersionString.ToString()} - {path}");
radioButton.JoinGroup(_noUpdateRadioButton);
_availableUpdatesBox.Add(radioButton);
_radioButtonToPathDictionary.Add(radioButton, path);
_availableUpdatesBox.Add(radioButton);
_radioButtonToPathDictionary.Add(radioButton, path);
radioButton.Show();
radioButton.Active = true;
}
else
{
GtkDialog.CreateErrorDialog("The specified file does not contain an update for the selected title!");
}
radioButton.Show();
radioButton.Active = true;
}
catch (Exception exception)
else
{
GtkDialog.CreateErrorDialog($"{exception.Message}. Errored File: {path}");
GtkDialog.CreateErrorDialog("The specified file does not contain an update for the selected title!");
}
}
catch (Exception exception)
{
GtkDialog.CreateErrorDialog($"{exception.Message}. Errored File: {path}");
}
}
}
@@ -143,24 +141,23 @@ namespace Ryujinx.Ui.Windows
private void AddButton_Clicked(object sender, EventArgs args)
{
using (FileChooserNative fileChooser = new FileChooserNative("Select update files", this, FileChooserAction.Open, "Add", "Cancel"))
using FileChooserNative fileChooser = new("Select update files", this, FileChooserAction.Open, "Add", "Cancel");
fileChooser.SelectMultiple = true;
FileFilter filter = new()
{
fileChooser.SelectMultiple = true;
Name = "Switch Game Updates",
};
filter.AddPattern("*.nsp");
FileFilter filter = new FileFilter()
fileChooser.AddFilter(filter);
if (fileChooser.Run() == (int)ResponseType.Accept)
{
foreach (string path in fileChooser.Filenames)
{
Name = "Switch Game Updates"
};
filter.AddPattern("*.nsp");
fileChooser.AddFilter(filter);
if (fileChooser.Run() == (int)ResponseType.Accept)
{
foreach (string path in fileChooser.Filenames)
{
AddUpdate(path);
}
AddUpdate(path);
}
}
}
@@ -193,7 +190,7 @@ namespace Ryujinx.Ui.Windows
}
}
JsonHelper.SerializeToFile(_updateJsonPath, _titleUpdateWindowData, SerializerContext.TitleUpdateMetadata);
JsonHelper.SerializeToFile(_updateJsonPath, _titleUpdateWindowData, _serializerContext.TitleUpdateMetadata);
_parent.UpdateGameTable();
@@ -205,4 +202,4 @@ namespace Ryujinx.Ui.Windows
Dispose();
}
}
}
}

View File

@@ -1,45 +1,43 @@
using Gtk;
using Pango;
using System;
namespace Ryujinx.Ui.Windows
{
public partial class UserProfilesManagerWindow : Window
{
private Box _mainBox;
private Label _selectedLabel;
private Box _selectedUserBox;
private Image _selectedUserImage;
private VBox _selectedUserInfoBox;
private Entry _selectedUserNameEntry;
private Label _selectedUserIdLabel;
private VBox _selectedUserButtonsBox;
private Button _saveProfileNameButton;
private Button _changeProfileImageButton;
private Box _usersTreeViewBox;
private Label _availableUsersLabel;
private Box _mainBox;
private Label _selectedLabel;
private Box _selectedUserBox;
private Image _selectedUserImage;
private Box _selectedUserInfoBox;
private Entry _selectedUserNameEntry;
private Label _selectedUserIdLabel;
private Box _selectedUserButtonsBox;
private Button _saveProfileNameButton;
private Button _changeProfileImageButton;
private Box _usersTreeViewBox;
private Label _availableUsersLabel;
private ScrolledWindow _usersTreeViewWindow;
private ListStore _tableStore;
private TreeView _usersTreeView;
private Box _bottomBox;
private Button _addButton;
private Button _deleteButton;
private Button _closeButton;
private ListStore _tableStore;
private TreeView _usersTreeView;
private Box _bottomBox;
private Button _addButton;
private Button _deleteButton;
private Button _closeButton;
private void InitializeComponent()
{
#pragma warning disable CS0612
//
// UserProfilesManagerWindow
//
CanFocus = false;
Resizable = false;
Modal = true;
CanFocus = false;
Resizable = false;
Modal = true;
WindowPosition = WindowPosition.Center;
DefaultWidth = 620;
DefaultHeight = 548;
TypeHint = Gdk.WindowTypeHint.Dialog;
DefaultWidth = 620;
DefaultHeight = 548;
TypeHint = Gdk.WindowTypeHint.Dialog;
//
// _mainBox
@@ -51,9 +49,9 @@ namespace Ryujinx.Ui.Windows
//
_selectedLabel = new Label("Selected User Profile:")
{
Margin = 15,
Margin = 15,
Attributes = new AttrList(),
Halign = Align.Start
Halign = Align.Start,
};
_selectedLabel.Attributes.Insert(new Pango.AttrWeight(Weight.Bold));
@@ -67,7 +65,7 @@ namespace Ryujinx.Ui.Windows
//
_selectedUserBox = new Box(Orientation.Horizontal, 0)
{
MarginLeft = 30
MarginStart = 30,
};
//
@@ -78,15 +76,18 @@ namespace Ryujinx.Ui.Windows
//
// _selectedUserInfoBox
//
_selectedUserInfoBox = new VBox(true, 0);
_selectedUserInfoBox = new Box(Orientation.Vertical, 0)
{
Homogeneous = true,
};
//
// _selectedUserNameEntry
//
_selectedUserNameEntry = new Entry("")
{
MarginLeft = 15,
MaxLength = (int)MaxProfileNameLength
MarginStart = 15,
MaxLength = (int)MaxProfileNameLength,
};
_selectedUserNameEntry.KeyReleaseEvent += SelectedUserNameEntry_KeyReleaseEvent;
@@ -95,16 +96,16 @@ namespace Ryujinx.Ui.Windows
//
_selectedUserIdLabel = new Label("")
{
MarginTop = 15,
MarginLeft = 15
MarginTop = 15,
MarginStart = 15,
};
//
// _selectedUserButtonsBox
//
_selectedUserButtonsBox = new VBox()
_selectedUserButtonsBox = new Box(Orientation.Vertical, 0)
{
MarginRight = 30
MarginEnd = 30,
};
//
@@ -112,10 +113,10 @@ namespace Ryujinx.Ui.Windows
//
_saveProfileNameButton = new Button()
{
Label = "Save Profile Name",
CanFocus = true,
Label = "Save Profile Name",
CanFocus = true,
ReceivesDefault = true,
Sensitive = false
Sensitive = false,
};
_saveProfileNameButton.Clicked += EditProfileNameButton_Pressed;
@@ -124,10 +125,10 @@ namespace Ryujinx.Ui.Windows
//
_changeProfileImageButton = new Button()
{
Label = "Change Profile Image",
CanFocus = true,
Label = "Change Profile Image",
CanFocus = true,
ReceivesDefault = true,
MarginTop = 10
MarginTop = 10,
};
_changeProfileImageButton.Clicked += ChangeProfileImageButton_Pressed;
@@ -136,9 +137,9 @@ namespace Ryujinx.Ui.Windows
//
_availableUsersLabel = new Label("Available User Profiles:")
{
Margin = 15,
Margin = 15,
Attributes = new AttrList(),
Halign = Align.Start
Halign = Align.Start,
};
_availableUsersLabel.Attributes.Insert(new Pango.AttrWeight(Weight.Bold));
@@ -147,12 +148,12 @@ namespace Ryujinx.Ui.Windows
//
_usersTreeViewWindow = new ScrolledWindow()
{
ShadowType = ShadowType.In,
CanFocus = true,
Expand = true,
MarginLeft = 30,
MarginRight = 30,
MarginBottom = 15
ShadowType = ShadowType.In,
CanFocus = true,
Expand = true,
MarginStart = 30,
MarginEnd = 30,
MarginBottom = 15,
};
//
@@ -175,9 +176,9 @@ namespace Ryujinx.Ui.Windows
//
_bottomBox = new Box(Orientation.Horizontal, 0)
{
MarginLeft = 30,
MarginRight = 30,
MarginBottom = 15
MarginStart = 30,
MarginEnd = 30,
MarginBottom = 15,
};
//
@@ -185,10 +186,10 @@ namespace Ryujinx.Ui.Windows
//
_addButton = new Button()
{
Label = "Add New Profile",
CanFocus = true,
Label = "Add New Profile",
CanFocus = true,
ReceivesDefault = true,
HeightRequest = 35
HeightRequest = 35,
};
_addButton.Clicked += AddButton_Pressed;
@@ -197,11 +198,11 @@ namespace Ryujinx.Ui.Windows
//
_deleteButton = new Button()
{
Label = "Delete Selected Profile",
CanFocus = true,
Label = "Delete Selected Profile",
CanFocus = true,
ReceivesDefault = true,
HeightRequest = 35,
MarginLeft = 10
HeightRequest = 35,
MarginStart = 10,
};
_deleteButton.Clicked += DeleteButton_Pressed;
@@ -210,16 +211,14 @@ namespace Ryujinx.Ui.Windows
//
_closeButton = new Button()
{
Label = "Close",
CanFocus = true,
Label = "Close",
CanFocus = true,
ReceivesDefault = true,
HeightRequest = 35,
WidthRequest = 80
HeightRequest = 35,
WidthRequest = 80,
};
_closeButton.Clicked += CloseButton_Pressed;
#pragma warning restore CS0612
ShowComponent();
}
@@ -253,4 +252,4 @@ namespace Ryujinx.Ui.Windows
ShowAll();
}
}
}
}

View File

@@ -13,7 +13,6 @@ using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Image = SixLabors.ImageSharp.Image;
using UserId = Ryujinx.HLE.HOS.Services.Account.Acc.UserId;
namespace Ryujinx.Ui.Windows
{
@@ -29,7 +28,7 @@ namespace Ryujinx.Ui.Windows
private Gdk.RGBA _selectedColor;
private ManualResetEvent _avatarsPreloadingEvent = new ManualResetEvent(false);
private readonly ManualResetEvent _avatarsPreloadingEvent = new(false);
public UserProfilesManagerWindow(AccountManager accountManager, ContentManager contentManager, VirtualFileSystem virtualFileSystem) : base($"Ryujinx {Program.Version} - Manage User Profiles")
{
@@ -37,24 +36,24 @@ namespace Ryujinx.Ui.Windows
InitializeComponent();
_selectedColor.Red = 0.212;
_selectedColor.Red = 0.212;
_selectedColor.Green = 0.843;
_selectedColor.Blue = 0.718;
_selectedColor.Blue = 0.718;
_selectedColor.Alpha = 1;
_accountManager = accountManager;
_contentManager = contentManager;
CellRendererToggle userSelectedToggle = new CellRendererToggle();
CellRendererToggle userSelectedToggle = new();
userSelectedToggle.Toggled += UserSelectedToggle_Toggled;
// NOTE: Uncomment following line when multiple selection of user profiles is supported.
//_usersTreeView.AppendColumn("Selected", userSelectedToggle, "active", 0);
_usersTreeView.AppendColumn("User Icon", new CellRendererPixbuf(), "pixbuf", 1);
_usersTreeView.AppendColumn("User Info", new CellRendererText(), "text", 2, "background-rgba", 3);
_usersTreeView.AppendColumn("User Info", new CellRendererText(), "text", 2, "background-rgba", 3);
_tableStore.SetSortColumnId(0, SortType.Descending);
RefreshList();
if (_contentManager.GetCurrentFirmwareVersion() != null)
@@ -77,8 +76,8 @@ namespace Ryujinx.Ui.Windows
if (userProfile.AccountState == AccountState.Open)
{
_selectedUserImage.Pixbuf = new Gdk.Pixbuf(userProfile.Image, 96, 96);
_selectedUserIdLabel.Text = userProfile.UserId.ToString();
_selectedUserImage.Pixbuf = new Gdk.Pixbuf(userProfile.Image, 96, 96);
_selectedUserIdLabel.Text = userProfile.UserId.ToString();
_selectedUserNameEntry.Text = userProfile.Name;
_deleteButton.Sensitive = userProfile.UserId != AccountManager.DefaultUserId;
@@ -111,7 +110,7 @@ namespace Ryujinx.Ui.Windows
Gdk.Pixbuf userPicture = (Gdk.Pixbuf)_tableStore.GetValue(selectedIter, 1);
string userName = _tableStore.GetValue(selectedIter, 2).ToString().Split("\n")[0];
string userId = _tableStore.GetValue(selectedIter, 2).ToString().Split("\n")[1];
string userId = _tableStore.GetValue(selectedIter, 2).ToString().Split("\n")[1];
// Unselect the first user.
_usersTreeView.Model.GetIterFirst(out TreeIter firstIter);
@@ -121,9 +120,9 @@ namespace Ryujinx.Ui.Windows
// Set new informations.
_tableStore.SetValue(selectedIter, 0, true);
_selectedUserImage.Pixbuf = userPicture;
_selectedUserNameEntry.Text = userName;
_selectedUserIdLabel.Text = userId;
_selectedUserImage.Pixbuf = userPicture;
_selectedUserNameEntry.Text = userName;
_selectedUserIdLabel.Text = userId;
_saveProfileNameButton.Sensitive = false;
// Open the selected one.
@@ -178,29 +177,27 @@ namespace Ryujinx.Ui.Windows
private void ProcessProfileImage(byte[] buffer)
{
using (Image image = Image.Load(buffer))
{
image.Mutate(x => x.Resize(256, 256));
using Image image = Image.Load(buffer);
using (MemoryStream streamJpg = MemoryStreamManager.Shared.GetStream())
{
image.SaveAsJpeg(streamJpg);
image.Mutate(x => x.Resize(256, 256));
_bufferImageProfile = streamJpg.ToArray();
}
}
using MemoryStream streamJpg = MemoryStreamManager.Shared.GetStream();
image.SaveAsJpeg(streamJpg);
_bufferImageProfile = streamJpg.ToArray();
}
private void ProfileImageFileChooser()
{
FileChooserNative fileChooser = new FileChooserNative("Import Custom Profile Image", this, FileChooserAction.Open, "Import", "Cancel")
FileChooserNative fileChooser = new("Import Custom Profile Image", this, FileChooserAction.Open, "Import", "Cancel")
{
SelectMultiple = false
SelectMultiple = false,
};
FileFilter filter = new FileFilter()
FileFilter filter = new()
{
Name = "Custom Profile Images"
Name = "Custom Profile Images",
};
filter.AddPattern("*.jpg");
filter.AddPattern("*.jpeg");
@@ -225,15 +222,15 @@ namespace Ryujinx.Ui.Windows
}
else
{
Dictionary<int, string> buttons = new Dictionary<int, string>()
Dictionary<int, string> buttons = new()
{
{ 0, "Import Image File" },
{ 1, "Select Firmware Avatar" }
{ 1, "Select Firmware Avatar" },
};
ResponseType responseDialog = GtkDialog.CreateCustomDialog("Profile Image Selection",
"Choose a Profile Image",
"You may import a custom profile image, or select an avatar from the system firmware.",
"You may import a custom profile image, or select an avatar from the system firmware.",
buttons, MessageType.Question);
if (responseDialog == 0)
@@ -242,9 +239,9 @@ namespace Ryujinx.Ui.Windows
}
else if (responseDialog == (ResponseType)1)
{
AvatarWindow avatarWindow = new AvatarWindow()
AvatarWindow avatarWindow = new()
{
NewUser = newUser
NewUser = newUser,
};
avatarWindow.DeleteEvent += AvatarWindow_DeleteEvent;
@@ -328,4 +325,4 @@ namespace Ryujinx.Ui.Windows
Close();
}
}
}
}