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:
216
src/Ryujinx/Ui/Windows/AboutWindow.Designer.cs
generated
216
src/Ryujinx/Ui/Windows/AboutWindow.Designer.cs
generated
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
78
src/Ryujinx/Ui/Windows/AmiiboWindow.Designer.cs
generated
78
src/Ryujinx/Ui/Windows/AmiiboWindow.Designer.cs
generated
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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
@@ -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();
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user