diff --git a/Bloxstrap/App.xaml.cs b/Bloxstrap/App.xaml.cs index 1b5a504b..4f52b588 100644 --- a/Bloxstrap/App.xaml.cs +++ b/Bloxstrap/App.xaml.cs @@ -17,8 +17,9 @@ using Bloxstrap.Models; using Bloxstrap.Models.Attributes; using Bloxstrap.UI.BootstrapperDialogs; -using Bloxstrap.UI.Menu.Views; +using Bloxstrap.UI.MessageBox; using Bloxstrap.Utility; +using Bloxstrap.UI; namespace Bloxstrap { @@ -57,15 +58,6 @@ public partial class App : Application public static System.Windows.Forms.NotifyIcon Notification { get; private set; } = null!; - // shorthand - public static MessageBoxResult ShowMessageBox(string message, MessageBoxImage icon = MessageBoxImage.None, MessageBoxButton buttons = MessageBoxButton.OK) - { - if (IsQuiet) - return MessageBoxResult.None; - - return MessageBox.Show(message, ProjectName, buttons, icon); - } - public static void Terminate(int code = Bootstrapper.ERROR_SUCCESS) { Logger.WriteLine($"[App::Terminate] Terminating with exit code {code}"); @@ -198,7 +190,7 @@ protected override void OnStartup(StartupEventArgs e) { IsSetupComplete = false; FastFlags.Load(); - new MainWindow().ShowDialog(); + Controls.ShowMenu(); } } else @@ -246,10 +238,13 @@ protected override void OnStartup(StartupEventArgs e) } else { - if (Process.GetProcessesByName(ProjectName).Length > 1) - ShowMessageBox($"{ProjectName} is currently running, likely as a background Roblox process. Please note that not all your changes will immediately apply until you close all currently open Roblox instances.", MessageBoxImage.Information); + if (Process.GetProcessesByName(ProjectName).Length > 1 && !IsQuiet) + FluentMessageBox.Show( + $"{ProjectName} is currently running, likely as a background Roblox process. Please note that not all your changes will immediately apply until you close all currently open Roblox instances.", + MessageBoxImage.Information + ); - new MainWindow().ShowDialog(); + Controls.ShowMenu(); } } else if (LaunchArgs.Length > 0) @@ -261,7 +256,10 @@ protected override void OnStartup(StartupEventArgs e) else if (LaunchArgs[0].StartsWith("roblox:")) { if (Settings.Prop.UseDisableAppPatch) - ShowMessageBox("Roblox was launched via a deeplink, however the desktop app is required for deeplink launching to work. Because you've opted to disable the desktop app, it will temporarily be re-enabled for this launch only.", MessageBoxImage.Information); + Controls.ShowMessageBox( + "Roblox was launched via a deeplink, however the desktop app is required for deeplink launching to work. Because you've opted to disable the desktop app, it will temporarily be re-enabled for this launch only.", + MessageBoxImage.Information + ); commandLine = $"--app --deeplink {LaunchArgs[0]}"; } diff --git a/Bloxstrap/Bloxstrap.csproj b/Bloxstrap/Bloxstrap.csproj index c2e0c579..cb645747 100644 --- a/Bloxstrap/Bloxstrap.csproj +++ b/Bloxstrap/Bloxstrap.csproj @@ -17,6 +17,10 @@ + + + + diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index 2676e9cc..6a276ae6 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -17,6 +17,7 @@ using Bloxstrap.Integrations; using Bloxstrap.Models; using Bloxstrap.Tools; +using Bloxstrap.UI; using Bloxstrap.UI.BootstrapperDialogs; namespace Bloxstrap @@ -126,6 +127,8 @@ public async Task Run() { App.Logger.WriteLine("[Bootstrapper::Run] Running bootstrapper"); + Controls.ShowMessageBox("hi :D", MessageBoxImage.Error, MessageBoxButton.YesNoCancel); + if (App.IsUninstall) { Uninstall(); @@ -230,7 +233,9 @@ private async Task CheckLatestVersion() if (!String.IsNullOrEmpty(switchDefaultPrompt)) { - MessageBoxResult result = App.Settings.Prop.ChannelChangeMode == ChannelChangeMode.Automatic ? MessageBoxResult.Yes : App.ShowMessageBox(switchDefaultPrompt, MessageBoxImage.Question, MessageBoxButton.YesNo); + MessageBoxResult result = App.Settings.Prop.ChannelChangeMode == ChannelChangeMode.Prompt + ? Controls.ShowMessageBox(switchDefaultPrompt, MessageBoxImage.Question, MessageBoxButton.YesNo) + : MessageBoxResult.Yes; if (result == MessageBoxResult.Yes) { @@ -263,7 +268,10 @@ private async Task StartRoblox() if (!File.Exists("C:\\Windows\\System32\\mfplat.dll")) { - App.ShowMessageBox("Roblox requires the use of Windows Media Foundation components. You appear to be missing them, likely because you are using an N edition of Windows. Please install them first, and then launch Roblox.", MessageBoxImage.Error); + Controls.ShowMessageBox( + "Roblox requires the use of Windows Media Foundation components. You appear to be missing them, likely because you are using an N edition of Windows. Please install them first, and then launch Roblox.", + MessageBoxImage.Error + ); Utilities.ShellExecute("https://support.microsoft.com/en-us/topic/media-feature-pack-list-for-windows-n-editions-c1c6fffa-d052-8338-7a79-a4bb980a700a"); Dialog?.CloseBootstrapper(); return; @@ -637,7 +645,14 @@ private void Uninstall() { App.Logger.WriteLine($"[Bootstrapper::Uninstall] Prompting to shut down all open Roblox instances"); - Dialog?.PromptShutdown(); + MessageBoxResult result = Controls.ShowMessageBox( + "Roblox is currently running, but must be closed before uninstalling Bloxstrap. Would you like close Roblox now?", + MessageBoxImage.Information, + MessageBoxButton.OKCancel + ); + + if (result != MessageBoxResult.OK) + Environment.Exit(ERROR_INSTALL_USEREXIT); try { @@ -742,7 +757,11 @@ private async Task InstallLatestVersion() if (Utilities.GetFreeDiskSpace(Directories.Base) < totalSizeRequired) { - App.ShowMessageBox($"{App.ProjectName} does not have enough disk space to download and install Roblox. Please free up some disk space and try again.", MessageBoxImage.Error); + Controls.ShowMessageBox( + $"{App.ProjectName} does not have enough disk space to download and install Roblox. Please free up some disk space and try again.", + MessageBoxImage.Error + ); + App.Terminate(ERROR_INSTALL_FAILURE); return; } @@ -910,7 +929,7 @@ public static void MigrateIntegrations() if (File.Exists(injectorLocation)) { - App.ShowMessageBox( + Controls.ShowMessageBox( "Roblox has now finished rolling out the new game client update, featuring 64-bit support and the Hyperion anticheat. ReShade does not work with this update, and so it has now been disabled and removed from Bloxstrap.\n\n"+ "Your ReShade configuration files will still be saved, and you can locate them by opening the folder where Bloxstrap is installed to, and navigating to the Integrations folder. You can choose to delete these if you want.", MessageBoxImage.Warning diff --git a/Bloxstrap/ProtocolHandler.cs b/Bloxstrap/ProtocolHandler.cs index a186c93e..77eac1ac 100644 --- a/Bloxstrap/ProtocolHandler.cs +++ b/Bloxstrap/ProtocolHandler.cs @@ -7,6 +7,7 @@ using Microsoft.Win32; using Bloxstrap.Enums; +using Bloxstrap.UI; namespace Bloxstrap { @@ -59,12 +60,14 @@ public static string ParseUri(string protocol) { if (val.ToLowerInvariant() != App.Settings.Prop.Channel.ToLowerInvariant() && App.Settings.Prop.ChannelChangeMode != ChannelChangeMode.Ignore) { - MessageBoxResult result = App.Settings.Prop.ChannelChangeMode == ChannelChangeMode.Automatic ? MessageBoxResult.Yes : App.ShowMessageBox( - $"{App.ProjectName} was launched with the Roblox build channel set to {val}, however your current preferred channel is {App.Settings.Prop.Channel}.\n\n" + - $"Would you like to switch channels from {App.Settings.Prop.Channel} to {val}?", - MessageBoxImage.Question, - MessageBoxButton.YesNo - ); + MessageBoxResult result = App.Settings.Prop.ChannelChangeMode == ChannelChangeMode.Automatic + ? MessageBoxResult.Yes + : Controls.ShowMessageBox( + $"{App.ProjectName} was launched with the Roblox build channel set to {val}, however your current preferred channel is {App.Settings.Prop.Channel}.\n\n" + + $"Would you like to switch channels from {App.Settings.Prop.Channel} to {val}?", + MessageBoxImage.Question, + MessageBoxButton.YesNo + ); if (result == MessageBoxResult.Yes) { diff --git a/Bloxstrap/Resources/MessageBox/Error.png b/Bloxstrap/Resources/MessageBox/Error.png new file mode 100644 index 00000000..278bdd4c Binary files /dev/null and b/Bloxstrap/Resources/MessageBox/Error.png differ diff --git a/Bloxstrap/Resources/MessageBox/Information.png b/Bloxstrap/Resources/MessageBox/Information.png new file mode 100644 index 00000000..3de3eec4 Binary files /dev/null and b/Bloxstrap/Resources/MessageBox/Information.png differ diff --git a/Bloxstrap/Resources/MessageBox/Question.png b/Bloxstrap/Resources/MessageBox/Question.png new file mode 100644 index 00000000..a5a6a10e Binary files /dev/null and b/Bloxstrap/Resources/MessageBox/Question.png differ diff --git a/Bloxstrap/Resources/MessageBox/Warning.png b/Bloxstrap/Resources/MessageBox/Warning.png new file mode 100644 index 00000000..80f4b4bc Binary files /dev/null and b/Bloxstrap/Resources/MessageBox/Warning.png differ diff --git a/Bloxstrap/UI/BootstrapperDialogs/BaseFunctions.cs b/Bloxstrap/UI/BootstrapperDialogs/BaseFunctions.cs new file mode 100644 index 00000000..c7d096d1 --- /dev/null +++ b/Bloxstrap/UI/BootstrapperDialogs/BaseFunctions.cs @@ -0,0 +1,24 @@ +using System; +using System.Windows; + +namespace Bloxstrap.UI.BootstrapperDialogs +{ + static class BaseFunctions + { + public static void ShowSuccess(string message, Action? callback) + { + Controls.ShowMessageBox(message, MessageBoxImage.Information); + + if (callback is not null) + callback(); + + App.Terminate(); + } + + public static void ShowError(string message) + { + Controls.ShowMessageBox($"An error occurred while starting Roblox\n\nDetails: {message}", MessageBoxImage.Error); + App.Terminate(Bootstrapper.ERROR_INSTALL_FAILURE); + } + } +} diff --git a/Bloxstrap/UI/BootstrapperDialogs/IBootstrapperDialog.cs b/Bloxstrap/UI/BootstrapperDialogs/IBootstrapperDialog.cs index 5b36844a..8e4a4ec3 100644 --- a/Bloxstrap/UI/BootstrapperDialogs/IBootstrapperDialog.cs +++ b/Bloxstrap/UI/BootstrapperDialogs/IBootstrapperDialog.cs @@ -16,6 +16,5 @@ public interface IBootstrapperDialog void CloseBootstrapper(); void ShowSuccess(string message, Action? callback = null); void ShowError(string message); - void PromptShutdown(); } } diff --git a/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/ByfronDialog.xaml.cs b/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/ByfronDialog.xaml.cs index 76c8c0c2..910f67e0 100644 --- a/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/ByfronDialog.xaml.cs +++ b/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/ByfronDialog.xaml.cs @@ -91,33 +91,9 @@ public ByfronDialog() public void CloseBootstrapper() => Dispatcher.BeginInvoke(this.Close); - public void ShowSuccess(string message, Action? callback) - { - App.ShowMessageBox(message, MessageBoxImage.Information); - - if (callback is not null) - callback(); - - App.Terminate(); - } - - public void ShowError(string message) - { - App.ShowMessageBox($"An error occurred while starting Roblox\n\nDetails: {message}", MessageBoxImage.Error); - App.Terminate(Bootstrapper.ERROR_INSTALL_FAILURE); - } + public void ShowSuccess(string message, Action? callback) => BaseFunctions.ShowSuccess(message, callback); - public void PromptShutdown() - { - MessageBoxResult result = App.ShowMessageBox( - "Roblox is currently running, but needs to close. Would you like close Roblox now?", - MessageBoxImage.Information, - MessageBoxButton.OKCancel - ); - - if (result != MessageBoxResult.OK) - Environment.Exit(Bootstrapper.ERROR_INSTALL_USEREXIT); - } + public void ShowError(string message) => BaseFunctions.ShowError(message); #endregion } } diff --git a/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/FluentDialog.xaml b/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/FluentDialog.xaml index 1d51f7a3..b5c1879d 100644 --- a/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/FluentDialog.xaml +++ b/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/FluentDialog.xaml @@ -24,7 +24,7 @@ - + diff --git a/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/FluentDialog.xaml.cs b/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/FluentDialog.xaml.cs index 559a2ab1..eab8e838 100644 --- a/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/FluentDialog.xaml.cs +++ b/Bloxstrap/UI/BootstrapperDialogs/WPF/Views/FluentDialog.xaml.cs @@ -84,34 +84,9 @@ public FluentDialog() public void CloseBootstrapper() => Dispatcher.BeginInvoke(this.Close); // TODO: make prompts use dialog view natively rather than using message dialog boxes + public void ShowSuccess(string message, Action? callback) => BaseFunctions.ShowSuccess(message, callback); - public void ShowSuccess(string message, Action? callback) - { - App.ShowMessageBox(message, MessageBoxImage.Information); - - if (callback is not null) - callback(); - - App.Terminate(); - } - - public void ShowError(string message) - { - App.ShowMessageBox($"An error occurred while starting Roblox\n\nDetails: {message}", MessageBoxImage.Error); - App.Terminate(Bootstrapper.ERROR_INSTALL_FAILURE); - } - - public void PromptShutdown() - { - MessageBoxResult result = App.ShowMessageBox( - "Roblox is currently running, but needs to close. Would you like close Roblox now?", - MessageBoxImage.Information, - MessageBoxButton.OKCancel - ); - - if (result != MessageBoxResult.OK) - Environment.Exit(Bootstrapper.ERROR_INSTALL_USEREXIT); - } + public void ShowError(string message) => BaseFunctions.ShowError(message); #endregion } } diff --git a/Bloxstrap/UI/BootstrapperDialogs/WinForms/DialogBase.cs b/Bloxstrap/UI/BootstrapperDialogs/WinForms/DialogBase.cs index af9b34ae..23c6c549 100644 --- a/Bloxstrap/UI/BootstrapperDialogs/WinForms/DialogBase.cs +++ b/Bloxstrap/UI/BootstrapperDialogs/WinForms/DialogBase.cs @@ -1,5 +1,4 @@ using System; -using System.Windows; using System.Windows.Forms; using Bloxstrap.Extensions; @@ -101,33 +100,9 @@ public virtual void CloseBootstrapper() Close(); } - public virtual void ShowSuccess(string message, Action? callback) - { - App.ShowMessageBox(message, MessageBoxImage.Information); - - if (callback is not null) - callback(); - - App.Terminate(); - } - - public virtual void ShowError(string message) - { - App.ShowMessageBox($"An error occurred while starting Roblox\n\nDetails: {message}", MessageBoxImage.Error); - App.Terminate(Bootstrapper.ERROR_INSTALL_FAILURE); - } + public virtual void ShowSuccess(string message, Action? callback) => BaseFunctions.ShowSuccess(message, callback); - public void PromptShutdown() - { - MessageBoxResult result = App.ShowMessageBox( - "Roblox is currently running, but needs to close. Would you like close Roblox now?", - MessageBoxImage.Information, - MessageBoxButton.OKCancel - ); - - if (result != MessageBoxResult.OK) - Environment.Exit(Bootstrapper.ERROR_INSTALL_USEREXIT); - } + public virtual void ShowError(string message) => BaseFunctions.ShowError(message); #endregion } } diff --git a/Bloxstrap/UI/Controls.cs b/Bloxstrap/UI/Controls.cs new file mode 100644 index 00000000..7a9b8994 --- /dev/null +++ b/Bloxstrap/UI/Controls.cs @@ -0,0 +1,26 @@ +using System.Windows; + +using Bloxstrap.Enums; +using Bloxstrap.UI.Menu.Views; +using Bloxstrap.UI.MessageBox; + +namespace Bloxstrap.UI +{ + static class Controls + { + public static void ShowMenu() => new MainWindow().ShowDialog(); + + public static MessageBoxResult ShowMessageBox(string message, MessageBoxImage icon = MessageBoxImage.None, MessageBoxButton buttons = MessageBoxButton.OK, MessageBoxResult defaultResult = MessageBoxResult.None) + { + switch (App.Settings.Prop.BootstrapperStyle) + { + case BootstrapperStyle.FluentDialog: + case BootstrapperStyle.ByfronDialog: + return FluentMessageBox.Show(message, icon, buttons, defaultResult); + + default: + return NativeMessageBox.Show(message, icon, buttons, defaultResult); + } + } + } +} diff --git a/Bloxstrap/UI/Menu/ViewModels/MainWindowViewModel.cs b/Bloxstrap/UI/Menu/ViewModels/MainWindowViewModel.cs index d4f398b0..3bda3a1e 100644 --- a/Bloxstrap/UI/Menu/ViewModels/MainWindowViewModel.cs +++ b/Bloxstrap/UI/Menu/ViewModels/MainWindowViewModel.cs @@ -10,6 +10,8 @@ using Wpf.Ui.Controls.Interfaces; using Wpf.Ui.Mvvm.Contracts; +using Bloxstrap.UI.MessageBox; + namespace Bloxstrap.UI.Menu.ViewModels { public class MainWindowViewModel @@ -35,7 +37,7 @@ private void ConfirmSettings() { if (string.IsNullOrEmpty(App.BaseDirectory)) { - App.ShowMessageBox("You must set an install location", MessageBoxImage.Error); + FluentMessageBox.Show("You must set an install location", MessageBoxImage.Error); return; } @@ -50,12 +52,15 @@ private void ConfirmSettings() } catch (UnauthorizedAccessException) { - App.ShowMessageBox($"{App.ProjectName} does not have write access to the install location you selected. Please choose another install location.", MessageBoxImage.Error); + FluentMessageBox.Show( + $"{App.ProjectName} does not have write access to the install location you selected. Please choose another install location.", + MessageBoxImage.Error + ); return; } catch (Exception ex) { - App.ShowMessageBox(ex.Message, MessageBoxImage.Error); + FluentMessageBox.Show(ex.Message, MessageBoxImage.Error); return; } @@ -67,7 +72,11 @@ private void ConfirmSettings() if (App.BaseDirectory != _originalBaseDirectory) { App.Logger.WriteLine($"[MainWindowViewModel::ConfirmSettings] Changing install location from {_originalBaseDirectory} to {App.BaseDirectory}"); - App.ShowMessageBox($"{App.ProjectName} will install to the new location you've set the next time it runs.", MessageBoxImage.Information); + + FluentMessageBox.Show( + $"{App.ProjectName} will install to the new location you've set the next time it runs.", + MessageBoxImage.Information + ); using RegistryKey registryKey = Registry.CurrentUser.CreateSubKey($@"Software\{App.ProjectName}"); registryKey.SetValue("InstallLocation", App.BaseDirectory); diff --git a/Bloxstrap/UI/MessageBox/FluentMessageBox.xaml b/Bloxstrap/UI/MessageBox/FluentMessageBox.xaml new file mode 100644 index 00000000..ca6f2ced --- /dev/null +++ b/Bloxstrap/UI/MessageBox/FluentMessageBox.xaml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + +