Merge pull request #807 from bluepilledgreat/feature/localisation

Feature/localisation
This commit is contained in:
pizzaboxer 2023-10-24 14:51:06 +01:00 committed by GitHub
commit f6dc303e14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
56 changed files with 4547 additions and 395 deletions

View File

@ -3,6 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Bloxstrap" xmlns:local="clr-namespace:Bloxstrap"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:converters="clr-namespace:Bloxstrap.Converters"
ShutdownMode="OnExplicitShutdown" ShutdownMode="OnExplicitShutdown"
DispatcherUnhandledException="GlobalExceptionHandler"> DispatcherUnhandledException="GlobalExceptionHandler">
<Application.Resources> <Application.Resources>
@ -13,6 +14,8 @@
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
<FontFamily x:Key="Rubik">pack://application:,,,/Resources/Fonts/#Rubik Light</FontFamily> <FontFamily x:Key="Rubik">pack://application:,,,/Resources/Fonts/#Rubik Light</FontFamily>
<converters:ResourceConverter x:Key="ResourceConverter" />
</ResourceDictionary> </ResourceDictionary>
</Application.Resources> </Application.Resources>
</Application> </Application>

View File

@ -213,7 +213,7 @@ namespace Bloxstrap
{ {
if (Process.GetProcessesByName(ProjectName).Length > 1 && !IsQuiet) if (Process.GetProcessesByName(ProjectName).Length > 1 && !IsQuiet)
Controls.ShowMessageBox( Controls.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.", Bloxstrap.Resources.Strings.Menu_AlreadyRunning,
MessageBoxImage.Information MessageBoxImage.Information
); );
@ -232,7 +232,7 @@ namespace Bloxstrap
{ {
if (Settings.Prop.UseDisableAppPatch) if (Settings.Prop.UseDisableAppPatch)
Controls.ShowMessageBox( 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.", Bloxstrap.Resources.Strings.Bootstrapper_DeeplinkTempEnabled,
MessageBoxImage.Information MessageBoxImage.Information
); );

View File

@ -40,12 +40,14 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
<PackageReference Include="DiscordRichPresence" Version="1.2.1.24" /> <PackageReference Include="DiscordRichPresence" Version="1.2.1.24" />
<PackageReference Include="Markdig" Version="0.33.0" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.18-beta"> <PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.18-beta">
<!--<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>--> <!--<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>-->
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="securifybv.ShellLink" Version="0.1.0" /> <PackageReference Include="securifybv.ShellLink" Version="0.1.0" />
<PackageReference Include="SharpZipLib" Version="1.4.2" /> <PackageReference Include="SharpZipLib" Version="1.4.2" />
<PackageReference Include="System.Resources.ResourceManager" Version="4.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -61,4 +63,19 @@
</AssemblyAttribute> </AssemblyAttribute>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Compile Update="Resources\Strings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Strings.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resources\Strings.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project> </Project>

View File

@ -137,7 +137,7 @@ namespace Bloxstrap
App.Logger.WriteLine(LOG_IDENT, "Performing connectivity check..."); App.Logger.WriteLine(LOG_IDENT, "Performing connectivity check...");
SetStatus("Connecting to Roblox..."); SetStatus(Resources.Strings.Bootstrapper_Status_Connecting);
try try
{ {
@ -148,12 +148,12 @@ namespace Bloxstrap
App.Logger.WriteLine(LOG_IDENT, "Connectivity check failed!"); App.Logger.WriteLine(LOG_IDENT, "Connectivity check failed!");
App.Logger.WriteException(LOG_IDENT, ex); App.Logger.WriteException(LOG_IDENT, ex);
string message = $"It's possible that something is preventing {App.ProjectName} from connecting to the internet. Please check and try again."; string message = Resources.Strings.Bootstrapper_Connectivity_Preventing;
if (ex.GetType() == typeof(HttpResponseException)) if (ex.GetType() == typeof(HttpResponseException))
message = "Roblox may be down right now. See status.roblox.com for more information. Please try again later."; message = Resources.Strings.Bootstrapper_Connectivity_RobloxDown;
else if (ex.GetType() == typeof(TaskCanceledException)) else if (ex.GetType() == typeof(TaskCanceledException))
message = "Bloxstrap timed out when trying to connect to three different Roblox deployment mirrors, indicating a poor internet connection. Please try again later."; message = Resources.Strings.Bootstrapper_Connectivity_TimedOut;
else if (ex.GetType() == typeof(AggregateException)) else if (ex.GetType() == typeof(AggregateException))
ex = ex.InnerException!; ex = ex.InnerException!;
@ -180,7 +180,7 @@ namespace Bloxstrap
{ {
Mutex.OpenExisting("Bloxstrap_SingletonMutex").Close(); Mutex.OpenExisting("Bloxstrap_SingletonMutex").Close();
App.Logger.WriteLine(LOG_IDENT, "Bloxstrap_SingletonMutex mutex exists, waiting..."); App.Logger.WriteLine(LOG_IDENT, "Bloxstrap_SingletonMutex mutex exists, waiting...");
SetStatus("Waiting for other instances..."); SetStatus(Resources.Strings.Bootstrapper_Status_WaitingOtherInstances);
mutexExists = true; mutexExists = true;
} }
catch (Exception) catch (Exception)
@ -231,7 +231,7 @@ namespace Bloxstrap
await mutex.ReleaseAsync(); await mutex.ReleaseAsync();
if (App.IsFirstRun && App.IsNoLaunch) if (App.IsFirstRun && App.IsNoLaunch)
Dialog?.ShowSuccess($"{App.ProjectName} has successfully installed"); Dialog?.ShowSuccess(Resources.Strings.Bootstrapper_SuccessfullyInstalled);
else if (!App.IsNoLaunch && !_cancelFired) else if (!App.IsNoLaunch && !_cancelFired)
await StartRoblox(); await StartRoblox();
} }
@ -263,8 +263,7 @@ namespace Bloxstrap
MessageBoxResult action = App.Settings.Prop.ChannelChangeMode switch MessageBoxResult action = App.Settings.Prop.ChannelChangeMode switch
{ {
ChannelChangeMode.Prompt => Controls.ShowMessageBox( ChannelChangeMode.Prompt => Controls.ShowMessageBox(
$"The channel you're currently on ({App.Settings.Prop.Channel}) is out of date, and appears to no longer be receiving updates.\n" + string.Format(Resources.Strings.Bootstrapper_ChannelOutOfDate, App.Settings.Prop.Channel, RobloxDeployment.DefaultChannel),
$"Would you like to switch to the default channel ({RobloxDeployment.DefaultChannel})?",
MessageBoxImage.Warning, MessageBoxImage.Warning,
MessageBoxButton.YesNo MessageBoxButton.YesNo
), ),
@ -291,7 +290,7 @@ namespace Bloxstrap
{ {
const string LOG_IDENT = "Bootstrapper::StartRoblox"; const string LOG_IDENT = "Bootstrapper::StartRoblox";
SetStatus("Starting {product}..."); SetStatus(Resources.Strings.Bootstrapper_Status_Starting);
if (_launchCommandLine == "--app" && App.Settings.Prop.UseDisableAppPatch) if (_launchCommandLine == "--app" && App.Settings.Prop.UseDisableAppPatch)
{ {
@ -303,7 +302,7 @@ namespace Bloxstrap
if (!File.Exists(Path.Combine(Paths.System, "mfplat.dll"))) if (!File.Exists(Path.Combine(Paths.System, "mfplat.dll")))
{ {
Controls.ShowMessageBox( 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.", Resources.Strings.Bootstrapper_WMFNotFound,
MessageBoxImage.Error MessageBoxImage.Error
); );
@ -635,7 +634,7 @@ namespace Bloxstrap
return; return;
} }
SetStatus($"Getting the latest {App.ProjectName}..."); SetStatus(Resources.Strings.Bootstrapper_Status_UpgradingBloxstrap);
try try
{ {
@ -676,7 +675,7 @@ namespace Bloxstrap
App.Logger.WriteException(LOG_IDENT, ex); App.Logger.WriteException(LOG_IDENT, ex);
Controls.ShowMessageBox( Controls.ShowMessageBox(
$"Bloxstrap was unable to auto-update to {releaseInfo.TagName}. Please update it manually by downloading and running the latest release from the GitHub page.", string.Format(Resources.Strings.Bootstrapper_AutoUpdateFailed, releaseInfo.TagName),
MessageBoxImage.Information MessageBoxImage.Information
); );
} }
@ -692,7 +691,7 @@ namespace Bloxstrap
App.Logger.WriteLine(LOG_IDENT, $"Prompting to shut down all open Roblox instances"); App.Logger.WriteLine(LOG_IDENT, $"Prompting to shut down all open Roblox instances");
MessageBoxResult result = Controls.ShowMessageBox( MessageBoxResult result = Controls.ShowMessageBox(
"Roblox is currently running, but must be closed before uninstalling Bloxstrap. Would you like close Roblox now?", Resources.Strings.Bootstrapper_Uninstall_RobloxRunning,
MessageBoxImage.Information, MessageBoxImage.Information,
MessageBoxButton.OKCancel MessageBoxButton.OKCancel
); );
@ -722,7 +721,7 @@ namespace Bloxstrap
App.Logger.WriteLine(LOG_IDENT, $"All Roblox processes closed"); App.Logger.WriteLine(LOG_IDENT, $"All Roblox processes closed");
} }
SetStatus($"Uninstalling {App.ProjectName}..."); SetStatus(Resources.Strings.Bootstrapper_Status_Uninstalling);
App.ShouldSaveConfigs = false; App.ShouldSaveConfigs = false;
bool robloxPlayerStillInstalled = true; bool robloxPlayerStillInstalled = true;
@ -841,7 +840,7 @@ namespace Bloxstrap
}; };
} }
Dialog?.ShowSuccess($"{App.ProjectName} has successfully uninstalled", callback); Dialog?.ShowSuccess(Resources.Strings.Bootstrapper_SuccessfullyUninstalled, callback);
} }
#endregion #endregion
@ -852,7 +851,7 @@ namespace Bloxstrap
_isInstalling = true; _isInstalling = true;
SetStatus(FreshInstall ? "Installing {product}..." : "Upgrading {product}..."); SetStatus(FreshInstall ? Resources.Strings.Bootstrapper_Status_Installing : Resources.Strings.Bootstrapper_Status_Upgrading);
Directory.CreateDirectory(Paths.Base); Directory.CreateDirectory(Paths.Base);
Directory.CreateDirectory(Paths.Downloads); Directory.CreateDirectory(Paths.Downloads);
@ -866,7 +865,7 @@ namespace Bloxstrap
if (Filesystem.GetFreeDiskSpace(Paths.Base) < totalSizeRequired) if (Filesystem.GetFreeDiskSpace(Paths.Base) < totalSizeRequired)
{ {
Controls.ShowMessageBox( Controls.ShowMessageBox(
$"{App.ProjectName} does not have enough disk space to download and install Roblox. Please free up some disk space and try again.", Resources.Strings.Bootstrapper_NotEnoughSpace,
MessageBoxImage.Error MessageBoxImage.Error
); );
@ -911,7 +910,7 @@ namespace Bloxstrap
if (Dialog is not null) if (Dialog is not null)
{ {
Dialog.ProgressStyle = ProgressBarStyle.Marquee; Dialog.ProgressStyle = ProgressBarStyle.Marquee;
SetStatus("Configuring {product}..."); SetStatus(Resources.Strings.Bootstrapper_Status_Configuring);
} }
// wait for all packages to finish extracting, with an exception for the webview2 runtime installer // wait for all packages to finish extracting, with an exception for the webview2 runtime installer
@ -1032,7 +1031,7 @@ namespace Bloxstrap
await ExtractPackage(package); await ExtractPackage(package);
} }
SetStatus("Installing WebView2, please wait..."); SetStatus(Resources.Strings.Bootstrapper_Status_InstallingWebView2);
ProcessStartInfo startInfo = new() ProcessStartInfo startInfo = new()
{ {
@ -1061,8 +1060,7 @@ namespace Bloxstrap
if (File.Exists(injectorLocation)) if (File.Exists(injectorLocation))
{ {
Controls.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"+ Resources.Strings.Bootstrapper_HyperionUpdateInfo,
"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 MessageBoxImage.Warning
); );
@ -1083,7 +1081,7 @@ namespace Bloxstrap
return; return;
} }
SetStatus("Applying Roblox modifications..."); SetStatus(Resources.Strings.Bootstrapper_Status_ApplyingModifications);
// set executable flags for fullscreen optimizations // set executable flags for fullscreen optimizations
App.Logger.WriteLine(LOG_IDENT, "Checking executable flags..."); App.Logger.WriteLine(LOG_IDENT, "Checking executable flags...");

View File

@ -0,0 +1,87 @@
using Bloxstrap.UI.ViewModels;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Markup;
using System.Windows;
using Markdig.Syntax;
using Markdig.Syntax.Inlines;
using Markdig;
namespace Bloxstrap.ControlsWpf
{
/// <summary>
/// TextBlock with markdown support. <br/>
/// Only supports text and urls.
/// </summary>
[ContentProperty("MarkdownText")]
[Localizability(LocalizationCategory.Text)]
class MarkdownTextBlock : TextBlock
{
public static readonly DependencyProperty MarkdownTextProperty = DependencyProperty.Register(
"MarkdownText",
typeof(string),
typeof(MarkdownTextBlock),
new FrameworkPropertyMetadata(
string.Empty,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
OnTextMarkdownChanged));
public MarkdownTextBlock(string markdownText)
{
MarkdownText = markdownText;
}
public MarkdownTextBlock()
{
}
[Localizability(LocalizationCategory.Text)]
public string MarkdownText
{
get => Inlines.ToString() ?? "";
set => SetValue(MarkdownTextProperty, value);
}
private static void OnTextMarkdownChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
var markdownTextBlock = dependencyObject as MarkdownTextBlock;
if (markdownTextBlock == null)
return;
MarkdownDocument document = Markdown.Parse((string)dependencyPropertyChangedEventArgs.NewValue);
ParagraphBlock? paragraphBlock = document.FirstOrDefault() as ParagraphBlock;
markdownTextBlock.Inlines.Clear();
if (paragraphBlock == null || paragraphBlock.Inline == null)
return;
foreach (var inline in paragraphBlock.Inline)
{
if (inline is LiteralInline literalInline)
{
markdownTextBlock.Inlines.Add(new Run(literalInline.ToString()));
}
else if (inline is LinkInline linkInline)
{
string? url = linkInline.Url;
string? text = linkInline.FirstChild?.ToString();
if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(text))
continue;
var link = new Hyperlink(new Run(text))
{
Command = GlobalViewModel.OpenWebpageCommand,
CommandParameter = url
};
link.SetResourceReference(Control.ForegroundProperty, "TextFillColorPrimaryBrush");
markdownTextBlock.Inlines.Add(link);
}
}
}
}
}

View File

@ -0,0 +1,30 @@
using System.Windows.Data;
namespace Bloxstrap.Converters
{
internal class ResourceConverter : IValueConverter
{
// parameter is the resource namespace prefix
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is null)
return "";
if (parameter is null)
return value.ToString()!;
string valueStr = value.ToString()!;
string parameterStr = parameter.ToString()!;
string resourceName = parameterStr + valueStr;
string resourceValue = Resources.Strings.ResourceManager.GetStringSafe(resourceName);
return resourceValue;
}
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException(nameof(ConvertBack));
}
}
}

View File

@ -0,0 +1,10 @@
namespace Bloxstrap.Enums.FlagPresets
{
public enum InGameMenuVersion
{
Default,
V1,
V2,
V4
}
}

View File

@ -0,0 +1,10 @@
namespace Bloxstrap.Enums.FlagPresets
{
public enum LightingMode
{
Default,
Voxel,
ShadowMap,
Future
}
}

View File

@ -0,0 +1,11 @@
namespace Bloxstrap.Enums.FlagPresets
{
public enum MSAAMode
{
Default,
x1,
x2,
x4,
x8
}
}

View File

@ -0,0 +1,9 @@
namespace Bloxstrap.Enums.FlagPresets
{
public enum MaterialVersion
{
Default,
Old,
New
}
}

View File

@ -0,0 +1,11 @@
namespace Bloxstrap.Enums.FlagPresets
{
public enum RenderingMode
{
Default,
Vulkan,
D3D11,
D3D10,
OpenGL
}
}

View File

@ -2,11 +2,11 @@
{ {
static class CursorTypeEx static class CursorTypeEx
{ {
public static IReadOnlyDictionary<string, CursorType> Selections => new Dictionary<string, CursorType> public static IReadOnlyCollection<CursorType> Selections => new CursorType[]
{ {
{ "Default", CursorType.Default }, CursorType.Default,
{ "2013 (Angular)", CursorType.From2013 }, CursorType.From2013,
{ "2006 (Cartoony)", CursorType.From2006 }, CursorType.From2006
}; };
} }
} }

View File

@ -2,13 +2,13 @@
{ {
static class EmojiTypeEx static class EmojiTypeEx
{ {
public static IReadOnlyDictionary<string, EmojiType> Selections => new Dictionary<string, EmojiType> public static IReadOnlyCollection<EmojiType> Selections => new EmojiType[]
{ {
{ "Default (Twemoji)", EmojiType.Default }, EmojiType.Default,
{ "Catmoji", EmojiType.Catmoji }, EmojiType.Catmoji,
{ "Windows 11", EmojiType.Windows11 }, EmojiType.Windows11,
{ "Windows 10", EmojiType.Windows10 }, EmojiType.Windows10,
{ "Windows 8", EmojiType.Windows8 }, EmojiType.Windows8
}; };
public static IReadOnlyDictionary<EmojiType, string> Filenames => new Dictionary<EmojiType, string> public static IReadOnlyDictionary<EmojiType, string> Filenames => new Dictionary<EmojiType, string>

View File

@ -0,0 +1,24 @@
using System.Resources;
namespace Bloxstrap.Extensions
{
static class ResourceManagerEx
{
/// <summary>
/// Returns the value of the specified string resource. <br/>
/// If the resource is not found, the resource name will be returned.
/// </summary>
public static string GetStringSafe(this ResourceManager manager, string name) => manager.GetStringSafe(name, null);
/// <summary>
/// Returns the value of the string resource localized for the specified culture. <br/>
/// If the resource is not found, the resource name will be returned.
/// </summary>
public static string GetStringSafe(this ResourceManager manager, string name, CultureInfo? culture)
{
string? resourceValue = manager.GetString(name, culture);
return resourceValue ?? name;
}
}
}

View File

@ -1,4 +1,5 @@
using System.Windows.Forms; using Bloxstrap.Enums.FlagPresets;
using System.Windows.Forms;
using Windows.Win32; using Windows.Win32;
using Windows.Win32.Graphics.Gdi; using Windows.Win32.Graphics.Gdi;
@ -57,45 +58,45 @@ namespace Bloxstrap
}; };
// only one missing here is Metal because lol // only one missing here is Metal because lol
public static IReadOnlyDictionary<string, string> RenderingModes => new Dictionary<string, string> public static IReadOnlyDictionary<RenderingMode, string> RenderingModes => new Dictionary<RenderingMode, string>
{ {
{ "Automatic", "None" }, { RenderingMode.Default, "None" },
{ "Vulkan", "Vulkan" }, { RenderingMode.Vulkan, "Vulkan" },
{ "Direct3D 11", "D3D11" }, { RenderingMode.D3D11, "D3D11" },
{ "Direct3D 10", "D3D10" }, { RenderingMode.D3D10, "D3D10" },
{ "OpenGL", "OpenGL" } { RenderingMode.OpenGL, "OpenGL" }
}; };
public static IReadOnlyDictionary<string, string> LightingModes => new Dictionary<string, string> public static IReadOnlyDictionary<LightingMode, string> LightingModes => new Dictionary<LightingMode, string>
{ {
{ "Chosen by game", "None" }, { LightingMode.Default, "None" },
{ "Voxel (Phase 1)", "Voxel" }, { LightingMode.Voxel, "Voxel" },
{ "ShadowMap (Phase 2)", "ShadowMap" }, { LightingMode.ShadowMap, "ShadowMap" },
{ "Future (Phase 3)", "Future" } { LightingMode.Future, "Future" }
}; };
public static IReadOnlyDictionary<string, string?> MSAAModes => new Dictionary<string, string?> public static IReadOnlyDictionary<MSAAMode, string?> MSAAModes => new Dictionary<MSAAMode, string?>
{ {
{ "Automatic", null }, { MSAAMode.Default, null },
{ "1x MSAA", "1" }, { MSAAMode.x1, "1" },
{ "2x MSAA", "2" }, { MSAAMode.x2, "2" },
{ "4x MSAA", "4" }, { MSAAMode.x4, "4" },
{ "8x MSAA", "8" } { MSAAMode.x8, "8" }
}; };
public static IReadOnlyDictionary<string, string> MaterialVersions => new Dictionary<string, string> public static IReadOnlyDictionary<MaterialVersion, string> MaterialVersions => new Dictionary<MaterialVersion, string>
{ {
{ "Chosen by game", "None" }, { MaterialVersion.Default, "None" },
{ "Old (Pre-2022)", "NewTexturePack" }, { MaterialVersion.Old, "NewTexturePack" },
{ "New (2022)", "OldTexturePack" } { MaterialVersion.New, "OldTexturePack" }
}; };
// this is one hell of a dictionary definition lmao // this is one hell of a dictionary definition lmao
// since these all set the same flags, wouldn't making this use bitwise operators be better? // since these all set the same flags, wouldn't making this use bitwise operators be better?
public static IReadOnlyDictionary<string, Dictionary<string, string?>> IGMenuVersions => new Dictionary<string, Dictionary<string, string?>> public static IReadOnlyDictionary<InGameMenuVersion, Dictionary<string, string?>> IGMenuVersions => new Dictionary<InGameMenuVersion, Dictionary<string, string?>>
{ {
{ {
"Default", InGameMenuVersion.Default,
new Dictionary<string, string?> new Dictionary<string, string?>
{ {
{ "DisableV2", null }, { "DisableV2", null },
@ -105,7 +106,7 @@ namespace Bloxstrap
}, },
{ {
"Version 1 (2015)", InGameMenuVersion.V1,
new Dictionary<string, string?> new Dictionary<string, string?>
{ {
{ "DisableV2", "True" }, { "DisableV2", "True" },
@ -115,7 +116,7 @@ namespace Bloxstrap
}, },
{ {
"Version 2 (2020)", InGameMenuVersion.V2,
new Dictionary<string, string?> new Dictionary<string, string?>
{ {
{ "DisableV2", "False" }, { "DisableV2", "False" },
@ -125,7 +126,7 @@ namespace Bloxstrap
}, },
{ {
"Version 4 (2023)", InGameMenuVersion.V4,
new Dictionary<string, string?> new Dictionary<string, string?>
{ {
{ "DisableV2", "True" }, { "DisableV2", "True" },
@ -195,7 +196,7 @@ namespace Bloxstrap
public string? GetPreset(string name) => GetValue(PresetFlags[name]); public string? GetPreset(string name) => GetValue(PresetFlags[name]);
public string GetPresetEnum(IReadOnlyDictionary<string, string> mapping, string prefix, string value) public T GetPresetEnum<T>(IReadOnlyDictionary<T, string> mapping, string prefix, string value) where T : Enum
{ {
foreach (var pair in mapping) foreach (var pair in mapping)
{ {

View File

@ -33,7 +33,7 @@ namespace Bloxstrap
_installLocation = Path.GetDirectoryName(Paths.Process)!; _installLocation = Path.GetDirectoryName(Paths.Process)!;
var result = Controls.ShowMessageBox( var result = Controls.ShowMessageBox(
$"It appears as if {App.ProjectName} hasn't been properly installed. Is it supposed to be installed at {_installLocation}?", string.Format(Resources.Strings.InstallChecker_NotInstalledProperly, _installLocation),
MessageBoxImage.Warning, MessageBoxImage.Warning,
MessageBoxButton.YesNo MessageBoxButton.YesNo
); );
@ -75,9 +75,7 @@ namespace Bloxstrap
App.Logger.WriteLine(LOG_IDENT, $"Drive has changed from {driveName} to {newDriveName}"); App.Logger.WriteLine(LOG_IDENT, $"Drive has changed from {driveName} to {newDriveName}");
Controls.ShowMessageBox( Controls.ShowMessageBox(
$"{App.ProjectName} has detected a drive letter change and has reconfigured its install location from the {driveName} drive to the {newDriveName} drive.\n" + string.Format(Resources.Strings.InstallChecker_DriveLetterChangeDetected, driveName, newDriveName),
"\n" +
$"While {App.ProjectName} will continue to work, it's recommended that you change the drive leter back to its original value as other installed applications can experience similar issues.",
MessageBoxImage.Warning, MessageBoxImage.Warning,
MessageBoxButton.OK MessageBoxButton.OK
); );
@ -90,7 +88,7 @@ namespace Bloxstrap
App.Logger.WriteLine(LOG_IDENT, $"Drive {driveName} does not exist anymore, and has likely been removed"); App.Logger.WriteLine(LOG_IDENT, $"Drive {driveName} does not exist anymore, and has likely been removed");
var result = Controls.ShowMessageBox( var result = Controls.ShowMessageBox(
$"{App.ProjectName} was originally installed to the {driveName} drive, but it appears to no longer be present. Would you like to continue and carry out a fresh install?", string.Format(Resources.Strings.InstallChecker_InstallDriveMissing, driveName),
MessageBoxImage.Warning, MessageBoxImage.Warning,
MessageBoxButton.OKCancel MessageBoxButton.OKCancel
); );
@ -168,7 +166,7 @@ namespace Bloxstrap
else else
{ {
result = Controls.ShowMessageBox( result = Controls.ShowMessageBox(
$"The version of {App.ProjectName} you've launched is different to the version you currently have installed.\nWould you like to upgrade your currently installed version?", Resources.Strings.InstallChecker_VersionDifferentThanInstalled,
MessageBoxImage.Question, MessageBoxImage.Question,
MessageBoxButton.YesNo MessageBoxButton.YesNo
); );
@ -234,8 +232,8 @@ namespace Bloxstrap
if (isAutoUpgrade) if (isAutoUpgrade)
{ {
App.NotifyIcon?.ShowAlert( App.NotifyIcon?.ShowAlert(
$"{App.ProjectName} has been upgraded to v{currentVersionInfo.ProductVersion}", string.Format(Resources.Strings.InstallChecker_Updated, currentVersionInfo.ProductVersion),
"See what's new in this version", Resources.Strings.InstallChecker_SeeWhatsNew,
30, 30,
(_, _) => Utilities.ShellExecute($"https://github.com/{App.ProjectRepository}/releases/tag/v{currentVersionInfo.ProductVersion}") (_, _) => Utilities.ShellExecute($"https://github.com/{App.ProjectRepository}/releases/tag/v{currentVersionInfo.ProductVersion}")
); );
@ -243,7 +241,7 @@ namespace Bloxstrap
else if (!App.IsQuiet) else if (!App.IsQuiet)
{ {
Controls.ShowMessageBox( Controls.ShowMessageBox(
$"{App.ProjectName} has been upgraded to v{currentVersionInfo.ProductVersion}", string.Format(Resources.Strings.InstallChecker_Updated, currentVersionInfo.ProductVersion),
MessageBoxImage.Information, MessageBoxImage.Information,
MessageBoxButton.OK MessageBoxButton.OK
); );

View File

@ -293,7 +293,7 @@
App.Logger.WriteLine(LOG_IDENT, $"Failed to get server location for {ActivityMachineAddress}"); App.Logger.WriteLine(LOG_IDENT, $"Failed to get server location for {ActivityMachineAddress}");
App.Logger.WriteException(LOG_IDENT, ex); App.Logger.WriteException(LOG_IDENT, ex);
return "N/A (lookup failed)"; return $"N/A ({Resources.Strings.ActivityTracker_LookupFailed})";
} }
locationCity = locationCity.ReplaceLineEndings(""); locationCity = locationCity.ReplaceLineEndings("");
@ -308,7 +308,7 @@
location = $"{locationCity}, {locationRegion}, {locationCountry}"; location = $"{locationCity}, {locationRegion}, {locationCountry}";
if (!ActivityInGame) if (!ActivityInGame)
return "N/A (left game)"; return $"N/A ({Resources.Strings.ActivityTracker_LeftGame})";
GeolocationCache[ActivityMachineAddress] = location; GeolocationCache[ActivityMachineAddress] = location;

View File

@ -91,8 +91,7 @@ namespace Bloxstrap
return; return;
MessageBoxResult result = Controls.ShowMessageBox( MessageBoxResult result = Controls.ShowMessageBox(
$"Roblox is attempting to set your channel to {channel}, however your current preferred channel is {App.Settings.Prop.Channel}.\n\n" + string.Format(Resources.Strings.ProtocolHandler_RobloxSwitchedChannel, channel, App.Settings.Prop.Channel),
$"Would you like to switch your preferred channel to {channel}?",
MessageBoxImage.Question, MessageBoxImage.Question,
MessageBoxButton.YesNo MessageBoxButton.YesNo
); );

2678
Bloxstrap/Resources/Strings.Designer.cs generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Menu.Appearance.Customisation.Description" xml:space="preserve">
<value>Configure other customizable Bootstrapper options.</value>
</data>
<data name="Menu.Appearance.Customisation.Title" xml:space="preserve">
<value>Bootstrapper customization</value>
</data>
<data name="Menu.Behaviour.Title" xml:space="preserve">
<value>Behavior</value>
</data>
<data name="Menu.Mods.Misc.DisableFullscreenOptimisations.Title" xml:space="preserve">
<value>Disable fullscreen optimizations</value>
</data>
</root>

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:base="clr-namespace:Bloxstrap.UI.Elements.Base" xmlns:base="clr-namespace:Bloxstrap.UI.Elements.Base"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d" mc:Ignorable="d"
Width="420" Width="420"
MinHeight="0" MinHeight="0"
@ -44,7 +45,7 @@
<Border.Background> <Border.Background>
<SolidColorBrush Color="{ui:ThemeResource SolidBackgroundFillColorSecondary}" Opacity="{Binding FooterOpacity, Mode=OneTime}" /> <SolidColorBrush Color="{ui:ThemeResource SolidBackgroundFillColorSecondary}" Opacity="{Binding FooterOpacity, Mode=OneTime}" />
</Border.Background> </Border.Background>
<Button Margin="0" Content="Cancel" Width="120" HorizontalAlignment="Right" IsEnabled="{Binding CancelEnabled, Mode=OneWay}" Command="{Binding CancelInstallCommand}" /> <Button Margin="0" Content="{x:Static resources:Strings.Common_Cancel}" Width="120" HorizontalAlignment="Right" IsEnabled="{Binding CancelEnabled, Mode=OneWay}" Command="{Binding CancelInstallCommand}" />
</Border> </Border>
</Grid> </Grid>
</base:WpfUiWindow> </base:WpfUiWindow>

View File

@ -43,6 +43,8 @@ namespace Bloxstrap.UI.Elements.Bootstrapper
{ {
InitializeComponent(); InitializeComponent();
this.buttonCancel.Text = Resources.Strings.Common_Cancel;
ScaleWindow(); ScaleWindow();
SetupDialog(); SetupDialog();
} }

View File

@ -43,6 +43,7 @@ namespace Bloxstrap.UI.Elements.Bootstrapper
InitializeComponent(); InitializeComponent();
this.IconBox.BackgroundImage = App.Settings.Prop.BootstrapperIcon.GetIcon().ToBitmap(); this.IconBox.BackgroundImage = App.Settings.Prop.BootstrapperIcon.GetIcon().ToBitmap();
this.buttonCancel.Text = Resources.Strings.Common_Cancel;
ScaleWindow(); ScaleWindow();
SetupDialog(); SetupDialog();

View File

@ -6,9 +6,10 @@
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.ContextMenu" xmlns:local="clr-namespace:Bloxstrap.UI.Elements.ContextMenu"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels.ContextMenu" xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels.ContextMenu"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
d:DataContext="{d:DesignInstance Type=models:LogTracerViewModel}" d:DataContext="{d:DesignInstance Type=models:LogTracerViewModel}"
mc:Ignorable="d" mc:Ignorable="d"
Title="Log tracer" Title="{x:Static resources:Strings.ContextMenu_LogTracer_Title}"
Width="800" Width="800"
Height="480" Height="480"
Background="{ui:ThemeResource ApplicationBackgroundBrush}" Background="{ui:ThemeResource ApplicationBackgroundBrush}"
@ -22,13 +23,13 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ui:TitleBar Grid.Row="0" Grid.ColumnSpan="2" Padding="8" x:Name="RootTitleBar" Title="Log tracer" ShowMinimize="True" ShowMaximize="True" CanMaximize="True" KeyboardNavigation.TabNavigation="None" Icon="pack://application:,,,/Bloxstrap.ico" /> <ui:TitleBar Grid.Row="0" Grid.ColumnSpan="2" Padding="8" x:Name="RootTitleBar" Title="{x:Static resources:Strings.ContextMenu_LogTracer_Title}" ShowMinimize="True" ShowMaximize="True" CanMaximize="True" KeyboardNavigation.TabNavigation="None" Icon="pack://application:,,,/Bloxstrap.ico" />
<StackPanel Grid.Row="1" Orientation="Horizontal" Background="{ui:ThemeResource ControlFillColorDefaultBrush}"> <StackPanel Grid.Row="1" Orientation="Horizontal" Background="{ui:ThemeResource ControlFillColorDefaultBrush}">
<ui:MenuItem Margin="4,8,0,8" Header="Keep on top" IsCheckable="True" Click="KeepOnTopMenuItem_Click" /> <ui:MenuItem Margin="4,8,0,8" Header="{x:Static resources:Strings.ContextMenu_LogTracer_KeepOnTop}" IsCheckable="True" Click="KeepOnTopMenuItem_Click" />
<ui:MenuItem Margin="0,8,0,8" Header="Scroll to end" IsCheckable="True" IsChecked="True" Click="AutoScrollMenuItem_Click" /> <ui:MenuItem Margin="0,8,0,8" Header="{x:Static resources:Strings.ContextMenu_LogTracer_ScrollToEnd}" IsCheckable="True" IsChecked="True" Click="AutoScrollMenuItem_Click" />
<ui:MenuItem Name="TextWrappingToggle" Margin="0,8,0,8" Header="Text wrapping" IsCheckable="True" IsChecked="False" /> <ui:MenuItem Name="TextWrappingToggle" Margin="0,8,0,8" Header="{x:Static resources:Strings.ContextMenu_LogTracer_TextWrapping}" IsCheckable="True" IsChecked="False" />
<ui:MenuItem Margin="0,8,4,8" Header="Locate log file" Command="{Binding LocateLogFileCommand, Mode=OneTime}" /> <ui:MenuItem Margin="0,8,4,8" Header="{x:Static resources:Strings.Common_LocateLogFile}" Command="{Binding LocateLogFileCommand, Mode=OneTime}" />
</StackPanel> </StackPanel>
<ScrollViewer x:Name="ScrollViewer" Grid.Row="2" VerticalAlignment="Top"> <ScrollViewer x:Name="ScrollViewer" Grid.Row="2" VerticalAlignment="Top">
@ -51,7 +52,7 @@
<StatusBarItem> <StatusBarItem>
<TextBlock> <TextBlock>
<TextBlock.Text> <TextBlock.Text>
<MultiBinding Mode="OneWay" StringFormat="Tracing {0}"> <MultiBinding Mode="OneWay" StringFormat="{x:Static resources:Strings.ContextMenu_LogTracer_TracingFormat}">
<Binding Path="LogFilename" /> <Binding Path="LogFilename" />
</MultiBinding> </MultiBinding>
</TextBlock.Text> </TextBlock.Text>

View File

@ -6,6 +6,7 @@
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.ContextMenu" xmlns:local="clr-namespace:Bloxstrap.UI.Elements.ContextMenu"
xmlns:base="clr-namespace:Bloxstrap.UI.Elements.Base" xmlns:base="clr-namespace:Bloxstrap.UI.Elements.Base"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d" mc:Ignorable="d"
Title="ContextMenuContainer" Title="ContextMenuContainer"
MinWidth="0" MinWidth="0"
@ -35,7 +36,7 @@
</MenuItem.Header> </MenuItem.Header>
</MenuItem> </MenuItem>
<Separator /> <Separator />
<MenuItem x:Name="RichPresenceMenuItem" Header="Discord Rich Presence" IsCheckable="True" IsChecked="True" Visibility="Collapsed" Click="RichPresenceMenuItem_Click" /> <MenuItem x:Name="RichPresenceMenuItem" Header="{x:Static resources:Strings.Common_DiscordRichPresence}" IsCheckable="True" IsChecked="True" Visibility="Collapsed" Click="RichPresenceMenuItem_Click" />
<MenuItem x:Name="InviteDeeplinkMenuItem" Visibility="Collapsed" Click="InviteDeeplinkMenuItem_Click"> <MenuItem x:Name="InviteDeeplinkMenuItem" Visibility="Collapsed" Click="InviteDeeplinkMenuItem_Click">
<MenuItem.Header> <MenuItem.Header>
<Grid> <Grid>
@ -44,7 +45,7 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<ui:SymbolIcon Grid.Column="0" Symbol="ClipboardLink24"/> <ui:SymbolIcon Grid.Column="0" Symbol="ClipboardLink24"/>
<TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="4,0,0,0" Text="Copy invite deeplink" /> <TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="4,0,0,0" Text="{x:Static resources:Strings.ContextMenu_CopyDeeplinkInvite}" />
</Grid> </Grid>
</MenuItem.Header> </MenuItem.Header>
</MenuItem> </MenuItem>
@ -56,7 +57,7 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<ui:SymbolIcon Grid.Column="0" Symbol="Info28"/> <ui:SymbolIcon Grid.Column="0" Symbol="Info28"/>
<TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="4,0,0,0" Text="See server details" /> <TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="4,0,0,0" Text="{x:Static resources:Strings.ContextMenu_SeeServerDetails}" />
</Grid> </Grid>
</MenuItem.Header> </MenuItem.Header>
</MenuItem> </MenuItem>
@ -68,11 +69,11 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<ui:SymbolIcon Grid.Column="0" Symbol="WindowHeaderHorizontalOff20"/> <ui:SymbolIcon Grid.Column="0" Symbol="WindowHeaderHorizontalOff20"/>
<TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="4,0,0,0" Text="Close Roblox" /> <TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="4,0,0,0" Text="{x:Static resources:Strings.ContextMenu_CloseRoblox}" />
</Grid> </Grid>
</MenuItem.Header> </MenuItem.Header>
</MenuItem> </MenuItem>
<MenuItem x:Name="LogTracerMenuItem" Header="Open log tracer" Visibility="Collapsed" Click="LogTracerMenuItem_Click" /> <MenuItem x:Name="LogTracerMenuItem" Header="{x:Static resources:Strings.ContextMenu_OpenLogTracer}" Visibility="Collapsed" Click="LogTracerMenuItem_Click" />
</ContextMenu> </ContextMenu>
</ui:UiWindow.ContextMenu> </ui:UiWindow.ContextMenu>
</base:WpfUiWindow> </base:WpfUiWindow>

View File

@ -127,7 +127,7 @@ namespace Bloxstrap.UI.Elements.ContextMenu
private void CloseRobloxMenuItem_Click(object sender, RoutedEventArgs e) private void CloseRobloxMenuItem_Click(object sender, RoutedEventArgs e)
{ {
MessageBoxResult result = Controls.ShowMessageBox( MessageBoxResult result = Controls.ShowMessageBox(
"Are you sure you want to close Roblox? This will forcefully end the process.", Bloxstrap.Resources.Strings.ContextMenu_CloseRobloxMessage,
MessageBoxImage.Warning, MessageBoxImage.Warning,
MessageBoxButton.YesNo MessageBoxButton.YesNo
); );

View File

@ -6,9 +6,10 @@
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.ContextMenu" xmlns:local="clr-namespace:Bloxstrap.UI.Elements.ContextMenu"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels.ContextMenu" xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels.ContextMenu"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
d:DataContext="{d:DesignInstance Type=models:ServerInformationViewModel}" d:DataContext="{d:DesignInstance Type=models:ServerInformationViewModel}"
mc:Ignorable="d" mc:Ignorable="d"
Title="Server information" Title="{x:Static resources:Strings.ContextMenu_ServerInformation_Title}"
MinWidth="0" MinWidth="0"
MinHeight="0" MinHeight="0"
Width="420" Width="420"
@ -24,7 +25,7 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ui:TitleBar Grid.Row="0" Grid.ColumnSpan="2" Padding="8" x:Name="RootTitleBar" Title="Server information" ShowMinimize="False" ShowMaximize="False" CanMaximize="False" KeyboardNavigation.TabNavigation="None" Icon="pack://application:,,,/Bloxstrap.ico" /> <ui:TitleBar Grid.Row="0" Grid.ColumnSpan="2" Padding="8" x:Name="RootTitleBar" Title="{x:Static resources:Strings.ContextMenu_ServerInformation_Title}" ShowMinimize="False" ShowMaximize="False" CanMaximize="False" KeyboardNavigation.TabNavigation="None" Icon="pack://application:,,,/Bloxstrap.ico" />
<Grid Grid.Row="1" Margin="16,8,16,16"> <Grid Grid.Row="1" Margin="16,8,16,16">
<Grid.RowDefinitions> <Grid.RowDefinitions>
@ -38,23 +39,23 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Margin="0,0,16,12" VerticalAlignment="Center" Text="Type" /> <TextBlock Grid.Row="0" Grid.Column="0" Margin="0,0,16,12" VerticalAlignment="Center" Text="{x:Static resources:Strings.ContextMenu_ServerInformation_Type}" />
<TextBlock Grid.Row="0" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding ServerType, Mode=OneWay}" /> <TextBlock Grid.Row="0" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding ServerType, Mode=OneWay}" />
<TextBlock Grid.Row="1" Grid.Column="0" Margin="0,0,16,12" VerticalAlignment="Center" Text="Instance ID" /> <TextBlock Grid.Row="1" Grid.Column="0" Margin="0,0,16,12" VerticalAlignment="Center" Text="{x:Static resources:Strings.ContextMenu_ServerInformation_InstanceId}" />
<TextBlock Grid.Row="1" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding InstanceId, Mode=OneWay}" /> <TextBlock Grid.Row="1" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding InstanceId, Mode=OneWay}" />
<TextBlock Grid.Row="2" Grid.Column="0" Margin="0,0,16,12" VerticalAlignment="Center" Text="Location" /> <TextBlock Grid.Row="2" Grid.Column="0" Margin="0,0,16,12" VerticalAlignment="Center" Text="{x:Static resources:Strings.ContextMenu_ServerInformation_Location}" />
<TextBlock Grid.Row="2" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding ServerLocation, Mode=OneWay}" /> <TextBlock Grid.Row="2" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding ServerLocation, Mode=OneWay}" />
<TextBlock Grid.Row="3" Grid.Column="0" Margin="0,0,16,0" VerticalAlignment="Center" Text="UDMUX proxied" /> <TextBlock Grid.Row="3" Grid.Column="0" Margin="0,0,16,0" VerticalAlignment="Center" Text="{x:Static resources:Strings.ContextMenu_ServerInformation_UdmuxProxied}" />
<TextBlock Grid.Row="3" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding UdmuxProxied, Mode=OneWay}" /> <TextBlock Grid.Row="3" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding UdmuxProxied, Mode=OneWay}" />
</Grid> </Grid>
<Border Grid.Row="2" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}"> <Border Grid.Row="2" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}">
<StackPanel Orientation="Horizontal" FlowDirection="LeftToRight" HorizontalAlignment="Right"> <StackPanel Orientation="Horizontal" FlowDirection="LeftToRight" HorizontalAlignment="Right">
<Button MinWidth="100" Content="Copy Instance ID" Command="{Binding CopyInstanceIdCommand, Mode=OneTime}" /> <Button MinWidth="100" Content="{x:Static resources:Strings.ContextMenu_ServerInformation_CopyInstanceId}" Command="{Binding CopyInstanceIdCommand, Mode=OneTime}" />
<Button Margin="12,0,0,0" MinWidth="100" Content="Close" Command="{Binding CloseWindowCommand, Mode=OneTime}" /> <Button Margin="12,0,0,0" MinWidth="100" Content="{x:Static resources:Strings.Common_Close}" Command="{Binding CloseWindowCommand, Mode=OneTime}" />
</StackPanel> </StackPanel>
</Border> </Border>
</Grid> </Grid>

View File

@ -5,8 +5,9 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Dialogs" xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Dialogs"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d" mc:Ignorable="d"
Title="Add FastFlag" Title="{x:Static resources:Strings.Dialog_AddFastFlag_Title}"
MinHeight="0" MinHeight="0"
Width="480" Width="480"
SizeToContent="Height" SizeToContent="Height"
@ -21,7 +22,7 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ui:TitleBar Grid.Row="0" Grid.ColumnSpan="2" Padding="8" Title="Add FastFlag" ShowMinimize="False" ShowMaximize="False" CanMaximize="False" KeyboardNavigation.TabNavigation="None" /> <ui:TitleBar Grid.Row="0" Grid.ColumnSpan="2" Padding="8" Title="{x:Static resources:Strings.Dialog_AddFastFlag_Title}" ShowMinimize="False" ShowMaximize="False" CanMaximize="False" KeyboardNavigation.TabNavigation="None" />
<Grid Grid.Row="1" Margin="15"> <Grid Grid.Row="1" Margin="15">
<Grid.RowDefinitions> <Grid.RowDefinitions>
@ -33,16 +34,16 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" MinWidth="100" Text="Name" Margin="0,0,0,12" /> <TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" MinWidth="100" Text="{x:Static resources:Strings.Common_Name}" Margin="0,0,0,12" />
<TextBox Grid.Row="0" Grid.Column="1" Name="FlagNameTextBox" Margin="0,0,0,12" /> <TextBox Grid.Row="0" Grid.Column="1" Name="FlagNameTextBox" Margin="0,0,0,12" />
<TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" MinWidth="100" Text="Value" /> <TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" MinWidth="100" Text="{x:Static resources:Strings.Common_Value}" />
<TextBox Grid.Row="1" Grid.Column="1" Name="FlagValueTextBox" /> <TextBox Grid.Row="1" Grid.Column="1" Name="FlagValueTextBox" />
</Grid> </Grid>
<Border Grid.Row="2" Margin="0,10,0,0" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}"> <Border Grid.Row="2" Margin="0,10,0,0" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}">
<StackPanel Orientation="Horizontal" FlowDirection="LeftToRight" HorizontalAlignment="Right"> <StackPanel Orientation="Horizontal" FlowDirection="LeftToRight" HorizontalAlignment="Right">
<Button MinWidth="100" Content="OK" Click="OKButton_Click"> <Button MinWidth="100" Content="{x:Static resources:Strings.Common_OK}" Click="OKButton_Click">
<Button.Style> <Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}"> <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Style.Triggers> <Style.Triggers>
@ -53,7 +54,7 @@
</Style> </Style>
</Button.Style> </Button.Style>
</Button> </Button>
<Button MinWidth="100" Margin="12,0,0,0" Content="Cancel" IsCancel="True" /> <Button MinWidth="100" Margin="12,0,0,0" Content="{x:Static resources:Strings.Common_Cancel}" IsCancel="True" />
</StackPanel> </StackPanel>
</Border> </Border>
</Grid> </Grid>

View File

@ -5,8 +5,9 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Dialogs" xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Dialogs"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d" mc:Ignorable="d"
Title="Import JSON" Title="{x:Static resources:Strings.Common_ImportJson}"
MinHeight="0" MinHeight="0"
Width="480" Width="480"
SizeToContent="Height" SizeToContent="Height"
@ -21,11 +22,11 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ui:TitleBar Grid.Row="0" Grid.ColumnSpan="2" Padding="8" Title="Import JSON" ShowMinimize="False" ShowMaximize="False" CanMaximize="False" KeyboardNavigation.TabNavigation="None" /> <ui:TitleBar Grid.Row="0" Grid.ColumnSpan="2" Padding="8" Title="{x:Static resources:Strings.Common_ImportJson}" ShowMinimize="False" ShowMaximize="False" CanMaximize="False" KeyboardNavigation.TabNavigation="None" />
<Grid Grid.Row="1" Margin="8,4,8,4"> <Grid Grid.Row="1" Margin="8,4,8,4">
<TextBox x:Name="JsonTextBox" Margin="5" AcceptsTab="True" AcceptsReturn="True" MinHeight="80" MaxHeight="480" /> <TextBox x:Name="JsonTextBox" Margin="5" AcceptsTab="True" AcceptsReturn="True" MinHeight="80" MaxHeight="480" />
<TextBlock IsHitTestVisible="False" Margin="18,14,0,0" Foreground="DarkGray"> <TextBlock IsHitTestVisible="False" Margin="18,14,0,0" Foreground="DarkGray" Text="{x:Static resources:Strings.Dialog_BulkAddFastFlag_Paste}">
<TextBlock.Style> <TextBlock.Style>
<Style TargetType="{x:Type TextBlock}"> <Style TargetType="{x:Type TextBlock}">
<Setter Property="Visibility" Value="Collapsed"/> <Setter Property="Visibility" Value="Collapsed"/>
@ -36,13 +37,12 @@
</Style.Triggers> </Style.Triggers>
</Style> </Style>
</TextBlock.Style> </TextBlock.Style>
Paste in your JSON here...
</TextBlock> </TextBlock>
</Grid> </Grid>
<Border Grid.Row="3" Margin="0,10,0,0" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}"> <Border Grid.Row="3" Margin="0,10,0,0" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}">
<StackPanel Orientation="Horizontal" FlowDirection="LeftToRight" HorizontalAlignment="Right"> <StackPanel Orientation="Horizontal" FlowDirection="LeftToRight" HorizontalAlignment="Right">
<Button MinWidth="100" Content="OK" Click="OKButton_Click"> <Button MinWidth="100" Content="{x:Static resources:Strings.Common_OK}" Click="OKButton_Click">
<Button.Style> <Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}"> <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Style.Triggers> <Style.Triggers>
@ -53,7 +53,7 @@
</Style> </Style>
</Button.Style> </Button.Style>
</Button> </Button>
<Button MinWidth="100" Margin="12,0,0,0" Content="Cancel" IsCancel="True" /> <Button MinWidth="100" Margin="12,0,0,0" Content="{x:Static resources:Strings.Common_Cancel}" IsCancel="True" />
</StackPanel> </StackPanel>
</Border> </Border>
</Grid> </Grid>

View File

@ -5,6 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Dialogs" xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Dialogs"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d" mc:Ignorable="d"
Width="480" Width="480"
MinHeight="0" MinHeight="0"
@ -19,7 +20,7 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ui:TitleBar Grid.Row="0" Grid.ColumnSpan="2" Padding="8" x:Name="RootTitleBar" ShowMinimize="False" ShowMaximize="False" CanMaximize="False" KeyboardNavigation.TabNavigation="None" Title="Connectivity error" /> <ui:TitleBar Grid.Row="0" Grid.ColumnSpan="2" Padding="8" x:Name="RootTitleBar" ShowMinimize="False" ShowMaximize="False" CanMaximize="False" KeyboardNavigation.TabNavigation="None" Title="{x:Static resources:Strings.Dialog_Connectivity_Title}" />
<Grid Grid.Row="1" Margin="16"> <Grid Grid.Row="1" Margin="16">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@ -30,14 +31,14 @@
<StackPanel Grid.Column="1"> <StackPanel Grid.Column="1">
<TextBlock x:Name="TitleTextBlock" Text="? is unable to connect to ?" FontSize="18" Foreground="{DynamicResource TextFillColorPrimaryBrush}" /> <TextBlock x:Name="TitleTextBlock" Text="? is unable to connect to ?" FontSize="18" Foreground="{DynamicResource TextFillColorPrimaryBrush}" />
<TextBlock x:Name="DescriptionTextBlock" Text="?" Margin="0,16,0,0" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorPrimaryBrush}" /> <TextBlock x:Name="DescriptionTextBlock" Text="?" Margin="0,16,0,0" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorPrimaryBrush}" />
<TextBlock Text="More information:" Margin="0,16,0,0" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorPrimaryBrush}" /> <TextBlock Text="{x:Static resources:Strings.Dialog_Connectivity_MoreInfo}" Margin="0,16,0,0" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorPrimaryBrush}" />
<RichTextBox x:Name="ErrorRichTextBox" Padding="8" Margin="0,8,0,0" Block.LineHeight="2" FontFamily="Courier New" IsReadOnly="True" /> <RichTextBox x:Name="ErrorRichTextBox" Padding="8" Margin="0,8,0,0" Block.LineHeight="2" FontFamily="Courier New" IsReadOnly="True" />
</StackPanel> </StackPanel>
</Grid> </Grid>
<Border Grid.Row="2" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}"> <Border Grid.Row="2" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}">
<StackPanel Orientation="Horizontal" FlowDirection="LeftToRight" HorizontalAlignment="Right"> <StackPanel Orientation="Horizontal" FlowDirection="LeftToRight" HorizontalAlignment="Right">
<Button x:Name="CloseButton" MinWidth="100" Content="Close" Margin="12,0,0,0" /> <Button x:Name="CloseButton" MinWidth="100" Content="{x:Static resources:Strings.Common_Close}" Margin="12,0,0,0" />
</StackPanel> </StackPanel>
</Border> </Border>
</Grid> </Grid>

View File

@ -18,7 +18,7 @@ namespace Bloxstrap.UI.Elements.Dialogs
{ {
InitializeComponent(); InitializeComponent();
TitleTextBlock.Text = $"{App.ProjectName} is unable to connect to {targetName}"; TitleTextBlock.Text = string.Format(Bloxstrap.Resources.Strings.Dialog_Connectivity_UnableToConnect, targetName);
DescriptionTextBlock.Text = description; DescriptionTextBlock.Text = description;
AddException(exception); AddException(exception);

View File

@ -5,7 +5,9 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Dialogs" xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Dialogs"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d" mc:Ignorable="d"
Title="{x:Static resources:Strings.Dialog_Exception_Title}"
Width="540" Width="540"
MinHeight="0" MinHeight="0"
SizeToContent="Height" SizeToContent="Height"
@ -19,7 +21,7 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ui:TitleBar Grid.Row="0" Grid.ColumnSpan="2" Padding="8" x:Name="RootTitleBar" ShowMinimize="False" ShowMaximize="False" CanMaximize="False" KeyboardNavigation.TabNavigation="None" /> <ui:TitleBar Grid.Row="0" Grid.ColumnSpan="2" Padding="8" x:Name="RootTitleBar" ShowMinimize="False" ShowMaximize="False" CanMaximize="False" KeyboardNavigation.TabNavigation="None" Title="{x:Static resources:Strings.Dialog_Exception_Title}" />
<Grid Grid.Row="1" Margin="16"> <Grid Grid.Row="1" Margin="16">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@ -28,21 +30,21 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Image Grid.Column="0" Width="32" Height="32" Margin="0,0,15,0" VerticalAlignment="Top" RenderOptions.BitmapScalingMode="HighQuality" Source="pack://application:,,,/Resources/MessageBox/Error.png" /> <Image Grid.Column="0" Width="32" Height="32" Margin="0,0,15,0" VerticalAlignment="Top" RenderOptions.BitmapScalingMode="HighQuality" Source="pack://application:,,,/Resources/MessageBox/Error.png" />
<StackPanel Grid.Column="1"> <StackPanel Grid.Column="1">
<TextBlock Text="An exception occurred while running Bloxstrap" FontSize="18" Foreground="{DynamicResource TextFillColorPrimaryBrush}" /> <TextBlock Text="{x:Static resources:Strings.Dialog_Exception_Info_1}" FontSize="18" Foreground="{DynamicResource TextFillColorPrimaryBrush}" />
<RichTextBox x:Name="ErrorRichTextBox" Padding="8" Margin="0,16,0,0" Block.LineHeight="2" FontFamily="Courier New" IsReadOnly="True" /> <RichTextBox x:Name="ErrorRichTextBox" Padding="8" Margin="0,16,0,0" Block.LineHeight="2" FontFamily="Courier New" IsReadOnly="True" />
<TextBlock Text="Please report this exception through a GitHub issue or in our Discord chat, along with a copy of the log file that was created." Margin="0,16,0,0" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorPrimaryBrush}" /> <TextBlock Text="{x:Static resources:Strings.Dialog_Exception_Info_2}" Margin="0,16,0,0" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorPrimaryBrush}" />
</StackPanel> </StackPanel>
</Grid> </Grid>
<Border Grid.Row="2" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}"> <Border Grid.Row="2" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}">
<StackPanel Orientation="Horizontal" FlowDirection="LeftToRight" HorizontalAlignment="Right"> <StackPanel Orientation="Horizontal" FlowDirection="LeftToRight" HorizontalAlignment="Right">
<Button x:Name="LocateLogFileButton" Content="Locate log file" /> <Button x:Name="LocateLogFileButton" Content="{x:Static resources:Strings.Common_LocateLogFile}" />
<ComboBox x:Name="ReportOptions" SelectedIndex="0" Padding="12,6,12,6" Margin="12,0,0,0"> <ComboBox x:Name="ReportOptions" SelectedIndex="0" Padding="12,6,12,6" Margin="12,0,0,0">
<ComboBoxItem Content="Submit report..." Visibility="Collapsed" /> <ComboBoxItem Content="{x:Static resources:Strings.Dialog_Exception_SubmitReport}" Visibility="Collapsed" />
<ComboBoxItem Content="Submit report via GitHub" /> <ComboBoxItem Content="{x:Static resources:Strings.Dialog_Exception_SubmitReportGithub}" Tag="github" />
<ComboBoxItem Content="Submit report via Discord" /> <ComboBoxItem Content="{x:Static resources:Strings.Dialog_Exception_SubmitReportDiscord}" Tag="discord" />
</ComboBox> </ComboBox>
<Button x:Name="CloseButton" MinWidth="100" Content="Close" Margin="12,0,0,0" /> <Button x:Name="CloseButton" MinWidth="100" Content="{x:Static resources:Strings.Common_Close}" Margin="12,0,0,0" />
</StackPanel> </StackPanel>
</Border> </Border>
</Grid> </Grid>

View File

@ -1,5 +1,6 @@
using System.Media; using System.Media;
using System.Windows; using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop; using System.Windows.Interop;
using Windows.Win32; using Windows.Win32;
@ -21,12 +22,10 @@ namespace Bloxstrap.UI.Elements.Dialogs
InitializeComponent(); InitializeComponent();
Title = RootTitleBar.Title = $"{App.ProjectName} Exception";
AddException(exception); AddException(exception);
if (!App.Logger.Initialized) if (!App.Logger.Initialized)
LocateLogFileButton.Content = "Copy log contents"; LocateLogFileButton.Content = Bloxstrap.Resources.Strings.Dialog_Exception_CopyLogContents;
LocateLogFileButton.Click += delegate LocateLogFileButton.Click += delegate
{ {
@ -38,16 +37,18 @@ namespace Bloxstrap.UI.Elements.Dialogs
ReportOptions.DropDownClosed += (sender, e) => ReportOptions.DropDownClosed += (sender, e) =>
{ {
string? selectionName = ReportOptions.SelectedItem.ToString(); ComboBoxItem? comboBoxItem = ReportOptions.SelectedItem as ComboBoxItem;
if (comboBoxItem is null)
return;
ReportOptions.SelectedIndex = 0; ReportOptions.SelectedIndex = 0;
if (selectionName is null) string? tag = comboBoxItem.Tag?.ToString();
return;
if (selectionName.EndsWith("GitHub")) if (tag == "github")
Utilities.ShellExecute($"https://github.com/{App.ProjectRepository}/issues"); Utilities.ShellExecute($"https://github.com/{App.ProjectRepository}/issues");
else if (selectionName.EndsWith("Discord")) else if (tag == "discord")
Utilities.ShellExecute("https://discord.gg/nKjV3mGq6R"); Utilities.ShellExecute("https://discord.gg/nKjV3mGq6R");
}; };

View File

@ -115,10 +115,29 @@ namespace Bloxstrap.UI.Elements.Dialogs
}; };
} }
// reuse existing strings
private static string GetTextForResult(MessageBoxResult result)
{
switch (result)
{
case MessageBoxResult.OK:
return Bloxstrap.Resources.Strings.Common_OK;
case MessageBoxResult.Cancel:
return Bloxstrap.Resources.Strings.Common_Cancel;
case MessageBoxResult.Yes:
return Bloxstrap.Resources.Strings.Common_Yes;
case MessageBoxResult.No:
return Bloxstrap.Resources.Strings.Common_No;
default:
Debug.Assert(false);
return result.ToString();
}
}
public void SetButton(Button button, MessageBoxResult result) public void SetButton(Button button, MessageBoxResult result)
{ {
button.Visibility = Visibility.Visible; button.Visibility = Visibility.Visible;
button.Content = result.ToString(); button.Content = GetTextForResult(result);
button.Click += (_, _) => button.Click += (_, _) =>
{ {
Result = result; Result = result;

View File

@ -7,8 +7,9 @@
xmlns:pages="clr-namespace:Bloxstrap.UI.Elements.Menu.Pages" xmlns:pages="clr-namespace:Bloxstrap.UI.Elements.Menu.Pages"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:base="clr-namespace:Bloxstrap.UI.Elements.Base" xmlns:base="clr-namespace:Bloxstrap.UI.Elements.Base"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d" mc:Ignorable="d"
Title="Bloxstrap Menu" Title="{x:Static resources:Strings.Menu_Title}"
MinWidth="960" MinWidth="960"
Width="960" Width="960"
Height="580" Height="580"
@ -23,7 +24,7 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ui:TitleBar Padding="8" x:Name="RootTitleBar" Grid.Row="0" ForceShutdown="False" MinimizeToTray="False" ShowHelp="True" HelpClicked="OpenWiki" UseSnapLayout="True" Title="Bloxstrap Menu" Icon="pack://application:,,,/Bloxstrap.ico" /> <ui:TitleBar Padding="8" x:Name="RootTitleBar" Grid.Row="0" ForceShutdown="False" MinimizeToTray="False" ShowHelp="True" HelpClicked="OpenWiki" UseSnapLayout="True" Title="{x:Static resources:Strings.Menu_Title}" Icon="pack://application:,,,/Bloxstrap.ico" />
<Grid x:Name="RootGrid" Grid.Row="1" Margin="12,12,0,0" Visibility="Visible"> <Grid x:Name="RootGrid" Grid.Row="1" Margin="12,12,0,0" Visibility="Visible">
<Grid.RowDefinitions> <Grid.RowDefinitions>
@ -37,16 +38,16 @@
<ui:NavigationFluent x:Name="RootNavigation" Grid.Row="1" Grid.Column="0" Margin="0,0,12,0" Frame="{Binding ElementName=RootFrame}" SelectedPageIndex="0" Visibility="{Binding NavigationVisibility, Mode=OneWay}"> <ui:NavigationFluent x:Name="RootNavigation" Grid.Row="1" Grid.Column="0" Margin="0,0,12,0" Frame="{Binding ElementName=RootFrame}" SelectedPageIndex="0" Visibility="{Binding NavigationVisibility, Mode=OneWay}">
<ui:NavigationFluent.Items> <ui:NavigationFluent.Items>
<ui:NavigationItem Content="Integrations" PageType="{x:Type pages:IntegrationsPage}" Icon="Add28" Tag="integrations" /> <ui:NavigationItem Content="{x:Static resources:Strings.Menu_Integrations_Title}" PageType="{x:Type pages:IntegrationsPage}" Icon="Add28" Tag="integrations" />
<ui:NavigationItem Content="Mods" PageType="{x:Type pages:ModsPage}" Icon="WrenchScrewdriver20" Tag="mods" /> <ui:NavigationItem Content="{x:Static resources:Strings.Menu_Mods_Title}" PageType="{x:Type pages:ModsPage}" Icon="WrenchScrewdriver20" Tag="mods" />
<ui:NavigationItem Content="FastFlags" PageType="{x:Type pages:FastFlagsPage}" Icon="Flag24" Tag="fastflags" /> <ui:NavigationItem Content="{x:Static resources:Strings.Menu_FastFlags_Title}" PageType="{x:Type pages:FastFlagsPage}" Icon="Flag24" Tag="fastflags" />
<ui:NavigationItem Content="Appearance" PageType="{x:Type pages:AppearancePage}" Icon="PaintBrush24" Tag="appearance" /> <ui:NavigationItem Content="{x:Static resources:Strings.Menu_Appearance_Title}" PageType="{x:Type pages:AppearancePage}" Icon="PaintBrush24" Tag="appearance" />
<ui:NavigationItem Content="Behaviour" PageType="{x:Type pages:BehaviourPage}" Icon="Settings24" Tag="behaviour" /> <ui:NavigationItem Content="{x:Static resources:Strings.Menu_Behaviour_Title}" PageType="{x:Type pages:BehaviourPage}" Icon="Settings24" Tag="behaviour" />
<ui:NavigationItem Content="Installation" PageType="{x:Type pages:InstallationPage}" Icon="HardDrive20" Tag="installation" /> <ui:NavigationItem Content="{x:Static resources:Strings.Menu_Installation_Title}" PageType="{x:Type pages:InstallationPage}" Icon="HardDrive20" Tag="installation" />
<ui:NavigationItem Content="About" PageType="{x:Type pages:AboutPage}" Icon="QuestionCircle48" Tag="about" /> <ui:NavigationItem Content="{x:Static resources:Strings.Menu_About_Title}" PageType="{x:Type pages:AboutPage}" Icon="QuestionCircle48" Tag="about" />
<ui:NavigationItem Content="FastFlag Editor" PageType="{x:Type pages:FastFlagEditorPage}" Tag="fastflageditor" Visibility="Collapsed" /> <ui:NavigationItem Content="{x:Static resources:Strings.Menu_FastFlagEditor_Title}" PageType="{x:Type pages:FastFlagEditorPage}" Tag="fastflageditor" Visibility="Collapsed" />
<ui:NavigationItem Content="Before you install..." PageType="{x:Type pages:PreInstallPage}" Tag="preinstall" Visibility="Collapsed" /> <ui:NavigationItem Content="{x:Static resources:Strings.Menu_PreInstall_Title}" PageType="{x:Type pages:PreInstallPage}" Tag="preinstall" Visibility="Collapsed" x:Name="PreInstallNavItem" />
</ui:NavigationFluent.Items> </ui:NavigationFluent.Items>
</ui:NavigationFluent> </ui:NavigationFluent>

View File

@ -22,6 +22,10 @@ namespace Bloxstrap.UI.Elements.Menu
App.Logger.WriteLine("MainWindow::MainWindow", "Initializing menu"); App.Logger.WriteLine("MainWindow::MainWindow", "Initializing menu");
DataContext = new MainWindowViewModel(this); DataContext = new MainWindowViewModel(this);
#if DEBUG // easier access
PreInstallNavItem.Visibility = System.Windows.Visibility.Visible;
#endif
} }
public void OpenWiki(object? sender, EventArgs e) => Utilities.ShellExecute($"https://github.com/{App.ProjectRepository}/wiki"); public void OpenWiki(object? sender, EventArgs e) => Utilities.ShellExecute($"https://github.com/{App.ProjectRepository}/wiki");

View File

@ -5,6 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels" xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="700" d:DesignWidth="800" d:DesignHeight="700" d:DesignWidth="800"
Title="AboutPage" Title="AboutPage"
@ -30,20 +31,20 @@
<TextBlock Grid.Column="0" Text="Bloxstrap" Margin="0,0,4,0" FontSize="24" FontWeight="Medium" /> <TextBlock Grid.Column="0" Text="Bloxstrap" Margin="0,0,4,0" FontSize="24" FontWeight="Medium" />
<TextBlock Grid.Column="1" Text="{Binding Version, Mode=OneTime}" Margin="4,0,0,2" VerticalAlignment="Bottom" FontSize="16" FontWeight="Medium" Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Grid.Column="1" Text="{Binding Version, Mode=OneTime}" Margin="4,0,0,2" VerticalAlignment="Bottom" FontSize="16" FontWeight="Medium" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</Grid> </Grid>
<TextBlock Text="An open-source, feature-packed alternative bootstrapper for Roblox" Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Text="{x:Static resources:Strings.Menu_About_Description_1}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock Text="Developed by pizzaboxer - if you like this, please consider leaving a star on GitHub!" Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Text="{x:Static resources:Strings.Menu_About_Description_2}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</Grid> </Grid>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<ui:Anchor Margin="0,16,4,0" Content="GitHub repository" Icon="Code24" NavigateUri="https://github.com/pizzaboxer/bloxstrap" /> <ui:Anchor Margin="0,16,4,0" Content="{x:Static resources:Strings.Menu_About_GithubRepository}" Icon="Code24" NavigateUri="https://github.com/pizzaboxer/bloxstrap" />
<ui:Anchor Margin="4,16,4,0" Content="Report an issue" Icon="Chat48" NavigateUri="https://github.com/pizzaboxer/bloxstrap/issues" /> <ui:Anchor Margin="4,16,4,0" Content="{x:Static resources:Strings.Menu_About_ReportIssue}" Icon="Chat48" NavigateUri="https://github.com/pizzaboxer/bloxstrap/issues" />
<ui:Anchor Margin="4,16,4,0" Content="Help and Information" Icon="BookQuestionMark24" NavigateUri="https://github.com/pizzaboxer/bloxstrap/wiki" /> <ui:Anchor Margin="4,16,4,0" Content="{x:Static resources:Strings.Menu_About_HelpInformation}" Icon="BookQuestionMark24" NavigateUri="https://github.com/pizzaboxer/bloxstrap/wiki" />
<ui:Anchor Margin="4,16,0,0" Content="Discord server" Icon="Chat48" NavigateUri="https://discord.gg/nKjV3mGq6R" /> <ui:Anchor Margin="4,16,0,0" Content="{x:Static resources:Strings.Menu_About_DiscordServer}" Icon="Chat48" NavigateUri="https://discord.gg/nKjV3mGq6R" />
</StackPanel> </StackPanel>
<StackPanel Visibility="{Binding BuildInformationVisibility, Mode=OneTime}"> <StackPanel Visibility="{Binding BuildInformationVisibility, Mode=OneTime}">
<TextBlock Text="Build Information" FontWeight="Medium" FontSize="20" Margin="0,16,0,0" /> <TextBlock Text="{x:Static resources:Strings.Menu_About_BuildInformation}" FontWeight="Medium" FontSize="20" Margin="0,16,0,0" />
<TextBlock Text="Using an unreleased version, I see?" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Text="{x:Static resources:Strings.Menu_About_UnreleasedVersion}" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<Grid Column="0" Margin="0,8,0,0"> <Grid Column="0" Margin="0,8,0,0">
<Grid.RowDefinitions> <Grid.RowDefinitions>
@ -76,8 +77,8 @@
</Grid> </Grid>
</StackPanel> </StackPanel>
<TextBlock Text="Contributors" FontWeight="Medium" FontSize="20" Margin="0,16,0,0" /> <TextBlock Text="{x:Static resources:Strings.Menu_About_Contributors}" FontWeight="Medium" FontSize="20" Margin="0,16,0,0" />
<TextBlock Text="These are the people who have made notable contributions to Bloxstrap, helping make it what it is." TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Text="{x:Static resources:Strings.Menu_About_Contributors_Description}" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<Grid Column="0" Margin="0,8,0,0"> <Grid Column="0" Margin="0,8,0,0">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<!-- bruh --> <!-- bruh -->
@ -185,7 +186,7 @@
</Grid> </Grid>
<ui:Anchor Margin="0,16,0,0" Content="See all code contributors" Icon="People48" NavigateUri="https://github.com/pizzaboxer/bloxstrap/graphs/contributors" /> <ui:Anchor Margin="0,16,0,0" Content="See all code contributors" Icon="People48" NavigateUri="https://github.com/pizzaboxer/bloxstrap/graphs/contributors" />
<TextBlock Text="Licenses" FontWeight="Medium" FontSize="18" Margin="0,16,0,0" /> <TextBlock Text="{x:Static resources:Strings.Menu_About_Licenses}" FontWeight="Medium" FontSize="18" Margin="0,16,0,0" />
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="*" /> <RowDefinition Height="*" />

View File

@ -4,36 +4,49 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="520" d:DesignWidth="800" d:DesignHeight="520" d:DesignWidth="800"
Title="AppearancePage" Title="AppearancePage"
Scrollable="True"> Scrollable="True">
<StackPanel Margin="0,0,14,14"> <StackPanel Margin="0,0,14,14">
<TextBlock Text="Configure how Bloxstrap should look." FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <TextBlock Text="{x:Static resources:Strings.Menu_Appearance_Description}" FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<ui:CardControl Margin="0,16,0,0"> <ui:CardControl Margin="0,16,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Theme" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Appearance_Theme_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Dark theme does not apply to Legacy or Vista styles." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Appearance_Theme_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ComboBox Width="200" Padding="10,5,10,5" ItemsSource="{Binding Themes.Keys, Mode=OneTime}" Text="{Binding Theme, Mode=TwoWay}" /> <ComboBox Width="200" Padding="10,5,10,5" ItemsSource="{Binding Themes, Mode=OneTime}" Text="{Binding Theme, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=., Converter={StaticResource ResourceConverter}, ConverterParameter='Enums.Theme.'}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</ui:CardControl> </ui:CardControl>
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Style" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Appearance_Style_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose how the bootstrapper should look." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Appearance_Style_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ComboBox Width="200" Padding="10,5,10,5" ItemsSource="{Binding Dialogs.Keys, Mode=OneTime}" Text="{Binding Dialog, Mode=TwoWay}" /> <ComboBox Width="200" Padding="10,5,10,5" ItemsSource="{Binding Dialogs, Mode=OneTime}" Text="{Binding Dialog, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=., Converter={StaticResource ResourceConverter}, ConverterParameter='Enums.BootstrapperStyle.'}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</ui:CardControl> </ui:CardControl>
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Icon" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Appearance_Icon_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose what icon the bootstrapper should use." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Appearance_Icon_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<Grid Width="200"> <Grid Width="200">
@ -46,7 +59,13 @@
<ImageBrush ImageSource="{Binding IconPreviewSource, Mode=OneWay}" /> <ImageBrush ImageSource="{Binding IconPreviewSource, Mode=OneWay}" />
</Border.Background> </Border.Background>
</Border> </Border>
<ComboBox Grid.Column="1" Margin="5,0,0,0" Padding="10,5,10,5" ItemsSource="{Binding Icons.Keys, Mode=OneTime}" Text="{Binding Icon, Mode=TwoWay}" /> <ComboBox Grid.Column="1" Margin="5,0,0,0" Padding="10,5,10,5" ItemsSource="{Binding Icons, Mode=OneTime}" Text="{Binding Icon, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=., Converter={StaticResource ResourceConverter}, ConverterParameter='Enums.BootstrapperIcon.'}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid> </Grid>
</ui:CardControl> </ui:CardControl>
<ui:CardExpander Margin="0,8,0,0" IsExpanded="False"> <ui:CardExpander Margin="0,8,0,0" IsExpanded="False">
@ -57,8 +76,8 @@
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<StackPanel Grid.Column="0"> <StackPanel Grid.Column="0">
<TextBlock FontSize="14" Text="Bootstrapper customization" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Appearance_Customisation_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Configure other customizable Bootstrapper options." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Appearance_Customisation_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</Grid> </Grid>
</ui:CardExpander.Header> </ui:CardExpander.Header>
@ -73,22 +92,22 @@
<ColumnDefinition Width="120" /> <ColumnDefinition Width="120" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Title" VerticalAlignment="Center" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <TextBlock Grid.Row="0" Grid.Column="0" Text="{x:Static resources:Strings.Menu_Appearance_CustomisationTitle_Title}" VerticalAlignment="Center" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<ui:TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Title, Mode=TwoWay}" /> <ui:TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Title, Mode=TwoWay}" />
<TextBlock Grid.Row="1" Grid.Column="1" Margin="0,4,0,0" FontSize="12" Text="The text that shows as the title of the bootstrapper." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Grid.Row="1" Grid.Column="1" Margin="0,4,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Appearance_CustomisationTitle_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock Grid.Row="2" Grid.Column="0" Margin="0,12,0,0" Text="Custom Icon" VerticalAlignment="Center" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <TextBlock Grid.Row="2" Grid.Column="0" Margin="0,12,0,0" Text="{x:Static resources:Strings.Menu_Appearance_CustomisationIcon_Title}" VerticalAlignment="Center" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<Grid Grid.Row="2" Grid.Column="1" Margin="0,12,0,0"> <Grid Grid.Row="2" Grid.Column="1" Margin="0,12,0,0">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Margin="0,0,4,0" Text="{Binding CustomIconLocation, Mode=TwoWay}" /> <TextBox Grid.Column="0" Margin="0,0,4,0" Text="{Binding CustomIconLocation, Mode=TwoWay}" />
<ui:Button Grid.Column="1" Margin="4,0,0,0" Height="35" Icon="Folder24" Content="Browse" Command="{Binding BrowseCustomIconLocationCommand}" /> <ui:Button Grid.Column="1" Margin="4,0,0,0" Height="35" Icon="Folder24" Content="{x:Static resources:Strings.Common_Browse}" Command="{Binding BrowseCustomIconLocationCommand}" />
</Grid> </Grid>
<TextBlock Grid.Row="3" Grid.Column="1" Margin="0,4,0,0" FontSize="12" Text="Must be a multi-size .ico file with sizes 16px to 128px. Set Icon as 'Custom' to use it." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Grid.Row="3" Grid.Column="1" Margin="0,4,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Appearance_CustomisationIcon_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</Grid> </Grid>
</ui:CardExpander> </ui:CardExpander>
<ui:Button Content="Preview" HorizontalAlignment="Stretch" Margin="0,8,0,0" Command="{Binding PreviewBootstrapperCommand}" /> <ui:Button Content="{x:Static resources:Strings.Menu_Appearance_Preview}" HorizontalAlignment="Stretch" Margin="0,8,0,0" Command="{Binding PreviewBootstrapperCommand}" />
</StackPanel> </StackPanel>
</ui:UiPage> </ui:UiPage>

View File

@ -6,6 +6,7 @@
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Menu.Pages" xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Menu.Pages"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels.Menu" xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels.Menu"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
d:DataContext="{d:DesignInstance Type=models:BehaviourViewModel}" d:DataContext="{d:DesignInstance Type=models:BehaviourViewModel}"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="800" d:DesignHeight="600" d:DesignWidth="800"
@ -13,13 +14,13 @@
Scrollable="True"> Scrollable="True">
<StackPanel Margin="0,0,14,14"> <StackPanel Margin="0,0,14,14">
<TextBlock Margin="0,0,0,8" Text="Configure what Bloxstrap should do when launching." FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <TextBlock Margin="0,0,0,8" Text="{x:Static resources:Strings.Menu_Behaviour_Description}" FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Create desktop icon" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Behaviour_CreateDesktopIcon_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Bloxstrap will place an icon on the desktop that launches Roblox the next time it launches." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Behaviour_CreateDesktopIcon_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding CreateDesktopIcon, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding CreateDesktopIcon, Mode=TwoWay}" />
@ -28,8 +29,8 @@
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Automatically update Bloxstrap" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Behaviour_AutoUpdate_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Bloxstrap will automatically check and update itself when launching Roblox." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Behaviour_AutoUpdate_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding UpdateCheckingEnabled, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding UpdateCheckingEnabled, Mode=TwoWay}" />
@ -43,8 +44,8 @@
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<StackPanel Grid.Column="0"> <StackPanel Grid.Column="0">
<TextBlock FontSize="14" Text="Channel" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Behaviour_Channel_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose which deployment channel Roblox should be downloaded from." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Behaviour_Channel_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
<ui:TextBox Grid.Column="1" Margin="8,0,8,0" Padding="10,5,10,5" Width="200" Text="{Binding SelectedChannel, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Delay=250}" /> <ui:TextBox Grid.Column="1" Margin="8,0,8,0" Padding="10,5,10,5" Width="200" Text="{Binding SelectedChannel, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Delay=250}" />
</Grid> </Grid>
@ -75,13 +76,13 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Margin="0,0,16,8" VerticalAlignment="Center" Text="Version" /> <TextBlock Grid.Row="0" Grid.Column="0" Margin="0,0,16,8" VerticalAlignment="Center" Text="{x:Static resources:Strings.Menu_Behaviour_Channel_Version}" />
<TextBlock Grid.Row="0" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding ChannelDeployInfo.Version, Mode=OneWay}" /> <TextBlock Grid.Row="0" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding ChannelDeployInfo.Version, Mode=OneWay}" />
<TextBlock Grid.Row="1" Grid.Column="0" Margin="0,0,16,8" VerticalAlignment="Center" Text="VersionGuid" /> <TextBlock Grid.Row="1" Grid.Column="0" Margin="0,0,16,8" VerticalAlignment="Center" Text="{x:Static resources:Strings.Menu_Behaviour_Channel_VersionGuid}" />
<TextBlock Grid.Row="1" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding ChannelDeployInfo.VersionGuid, Mode=OneWay}" /> <TextBlock Grid.Row="1" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding ChannelDeployInfo.VersionGuid, Mode=OneWay}" />
<TextBlock Grid.Row="2" Grid.Column="0" Margin="0,0,16,0" VerticalAlignment="Center" Text="Deployed" /> <TextBlock Grid.Row="2" Grid.Column="0" Margin="0,0,16,0" VerticalAlignment="Center" Text="{x:Static resources:Strings.Menu_Behaviour_Channel_Deployed}" />
<TextBlock Grid.Row="2" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding ChannelDeployInfo.Timestamp, Mode=OneWay}" /> <TextBlock Grid.Row="2" Grid.Column="1" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{Binding ChannelDeployInfo.Timestamp, Mode=OneWay}" />
<StackPanel Grid.Row="3" Grid.ColumnSpan="2" Margin="0,16,0,0" Orientation="Horizontal"> <StackPanel Grid.Row="3" Grid.ColumnSpan="2" Margin="0,16,0,0" Orientation="Horizontal">
@ -96,7 +97,7 @@
</Style> </Style>
</StackPanel.Style> </StackPanel.Style>
<Image Grid.Column="0" Width="24" Height="24" RenderOptions.BitmapScalingMode="HighQuality" Source="pack://application:,,,/Resources/MessageBox/Warning.png" /> <Image Grid.Column="0" Width="24" Height="24" RenderOptions.BitmapScalingMode="HighQuality" Source="pack://application:,,,/Resources/MessageBox/Warning.png" />
<TextBlock Margin="8,0,0,0" VerticalAlignment="Center" Text="This channel is out of date, and is likely no longer being updated. Please use another channel." /> <TextBlock Margin="8,0,0,0" VerticalAlignment="Center" Text="{x:Static resources:Strings.Menu_Behaviour_Channel_Outdated}" />
</StackPanel> </StackPanel>
</Grid> </Grid>
@ -151,11 +152,17 @@
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Automatic channel change action" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Behaviour_AutoChannelChange_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Roblox or Bloxstrap may try to change your preferred channel." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Behaviour_AutoChannelChange_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ComboBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" ItemsSource="{Binding ChannelChangeModes.Keys, Mode=OneTime}" Text="{Binding SelectedChannelChangeMode, Mode=TwoWay}" /> <ComboBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" ItemsSource="{Binding ChannelChangeModes, Mode=OneTime}" Text="{Binding SelectedChannelChangeMode, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=., Converter={StaticResource ResourceConverter}, ConverterParameter='Enums.ChannelChangeMode.'}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</ui:CardControl> </ui:CardControl>
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
@ -170,8 +177,8 @@
</ui:CardControl.Style> </ui:CardControl.Style>
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Force Roblox reinstallation" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Behaviour_ForceRobloxReinstall_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Roblox will be installed fresh on next launch." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Behaviour_ForceRobloxReinstall_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding ForceRobloxReinstallation, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding ForceRobloxReinstallation, Mode=TwoWay}" />

View File

@ -5,6 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Menu.Pages" xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Menu.Pages"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" d:DesignHeight="450" d:DesignWidth="800"
Title="FastFlagEditorPage" Title="FastFlagEditorPage"
@ -17,12 +18,12 @@
<RowDefinition Height="*" /> <RowDefinition Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock Grid.Row="0" Margin="0,0,0,16" Text="Manage your own FastFlags. Double click a column to edit." FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <TextBlock Grid.Row="0" Margin="0,0,0,16" Text="{x:Static resources:Strings.Menu_FastFlagEditor_Description}" FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<StackPanel Grid.Row="1" Margin="0,0,0,16" Orientation="Horizontal"> <StackPanel Grid.Row="1" Margin="0,0,0,16" Orientation="Horizontal">
<ui:Button Icon="ArrowLeft48" Content="Back" Click="BackButton_Click" /> <ui:Button Icon="ArrowLeft48" Content="{x:Static resources:Strings.Menu_FastFlagEditor_Back}" Click="BackButton_Click" />
<ui:Button Icon="Add28" Content="Add new" Click="AddButton_Click" Margin="12,0,0,0" /> <ui:Button Icon="Add28" Content="{x:Static resources:Strings.Menu_FastFlagEditor_AddNew}" Click="AddButton_Click" Margin="12,0,0,0" />
<ui:Button Icon="Delete48" Content="Delete selected" Click="DeleteButton_Click" Appearance="Danger" Margin="12,0,0,0"> <ui:Button Icon="Delete48" Content="{x:Static resources:Strings.Menu_FastFlagEditor_DeleteSelected}" Click="DeleteButton_Click" Appearance="Danger" Margin="12,0,0,0">
<ui:Button.Style> <ui:Button.Style>
<Style TargetType="ui:Button" BasedOn="{StaticResource {x:Type ui:Button}}"> <Style TargetType="ui:Button" BasedOn="{StaticResource {x:Type ui:Button}}">
<Style.Triggers> <Style.Triggers>
@ -33,11 +34,11 @@
</Style> </Style>
</ui:Button.Style> </ui:Button.Style>
</ui:Button> </ui:Button>
<ToggleButton x:Name="TogglePresetsButton" Content="Show preset flags" Click="ToggleButton_Click" Margin="12,0,0,0" /> <ToggleButton x:Name="TogglePresetsButton" Content="{x:Static resources:Strings.Menu_FastFlagEditor_ShowPresetFlags}" Click="ToggleButton_Click" Margin="12,0,0,0" />
<ui:Button Icon="ArrowImport24" Content="Import JSON" Margin="12,0,0,0" Click="ImportJSONButton_Click" /> <ui:Button Icon="ArrowImport24" Content="{x:Static resources:Strings.Common_ImportJson}" Margin="12,0,0,0" Click="ImportJSONButton_Click" />
</StackPanel> </StackPanel>
<ui:TextBox x:Name="SearchTextBox" Grid.Row="2" Margin="0,0,0,16" Icon="Search32" PlaceholderText="Search" TextChanged="SearchTextBox_TextChanged" /> <ui:TextBox x:Name="SearchTextBox" Grid.Row="2" Margin="0,0,0,16" Icon="Search32" PlaceholderText="{x:Static resources:Strings.Menu_FastFlagEditor_Search}" TextChanged="SearchTextBox_TextChanged" />
<DataGrid Name="DataGrid" Grid.Row="3" HeadersVisibility="Column" GridLinesVisibility="Horizontal" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" CellEditEnding="DataGrid_CellEditEnding"> <DataGrid Name="DataGrid" Grid.Row="3" HeadersVisibility="Column" GridLinesVisibility="Horizontal" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" CellEditEnding="DataGrid_CellEditEnding">
<DataGrid.Style> <DataGrid.Style>
@ -87,8 +88,8 @@
</DataGrid.CellStyle> </DataGrid.CellStyle>
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" /> <DataGridTextColumn Header="{x:Static resources:Strings.Common_Name}" Binding="{Binding Name}" />
<DataGridTextColumn Header="Value" Binding="{Binding Value}" Width="*" /> <DataGridTextColumn Header="{x:Static resources:Strings.Common_Value}" Binding="{Binding Value}" Width="*" />
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>
</Grid> </Grid>

View File

@ -5,13 +5,15 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels" xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
xmlns:controls="clr-namespace:Bloxstrap.ControlsWpf"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="1000" d:DesignWidth="800" d:DesignHeight="1000" d:DesignWidth="800"
Title="FastFlagsPage" Title="FastFlagsPage"
Scrollable="True" Scrollable="True"
Loaded="Page_Loaded"> Loaded="Page_Loaded">
<StackPanel Margin="0,0,14,14"> <StackPanel Margin="0,0,14,14">
<TextBlock Margin="0,0,0,16" Text="Control how specific Roblox engine parameters and features are configured." FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <TextBlock Margin="0,0,0,16" Text="{x:Static resources:Strings.Menu_FastFlags_Description}" FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@ -21,26 +23,26 @@
<ui:CardAction Grid.Column="0" Margin="0,0,4,0" Icon="EditSettings24" Command="{Binding OpenFastFlagEditorCommand}"> <ui:CardAction Grid.Column="0" Margin="0,0,4,0" Icon="EditSettings24" Command="{Binding OpenFastFlagEditorCommand}">
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="FastFlag Editor" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlagEditor_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Manage your own FastFlags." Padding="0,0,16,0" Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Editor_Description}" Padding="0,0,16,0" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardAction> </ui:CardAction>
<ui:CardAction Grid.Column="1" Margin="4,0,0,0" Icon="BookQuestionMark24" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/A-guide-to-FastFlags"> <ui:CardAction Grid.Column="1" Margin="4,0,0,0" Icon="BookQuestionMark24" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/A-guide-to-FastFlags">
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Help" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Common_Help}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Learn more about FastFlags." Padding="0,0,16,0" Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Help_Description}" Padding="0,0,16,0" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardAction> </ui:CardAction>
</Grid> </Grid>
<StackPanel Visibility="{Binding ShowDebugFlags, Mode=OneTime}"> <StackPanel Visibility="{Binding ShowDebugFlags, Mode=OneTime}">
<TextBlock Text="Debug" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" /> <TextBlock Text="{x:Static resources:Strings.Menu_FastFlags_Presets_Debug_Title}" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="HTTP request logging" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_Debug_HttpRequestLogging_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Enables logging of HTTP requests (DFLogHttpTraceLight=12)." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_Debug_HttpRequestLogging_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding HttpRequestLogging, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding HttpRequestLogging, Mode=TwoWay}" />
@ -48,8 +50,8 @@
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="HTTP proxy address" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_Debug_HttpProxyAddress_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Set blank if not using a proxy. Don't forget to add cacert.pem as a mod." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_Debug_HttpProxyAddress_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:TextBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" Text="{Binding HttpRequestProxy, Mode=TwoWay}" /> <ui:TextBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" Text="{Binding HttpRequestProxy, Mode=TwoWay}" />
@ -57,20 +59,16 @@
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Flag state overlay" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_Debug_FlagStateOverlay_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Show values of specified flags during runtime. Each flag is comma separated." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_Debug_FlagStateOverlay_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:TextBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" Text="{Binding StateOverlayFlags, Mode=TwoWay}" /> <ui:TextBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" Text="{Binding StateOverlayFlags, Mode=TwoWay}" />
</ui:CardControl> </ui:CardControl>
</StackPanel> </StackPanel>
<TextBlock Text="Presets" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" /> <TextBlock Text="{x:Static resources:Strings.Common_Presets}" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
<TextBlock Foreground="{DynamicResource TextFillColorSecondaryBrush}"> <controls:MarkdownTextBlock MarkdownText="{Binding Direct3DExclusiveFullscreenInfoText}"/>
FastFlag preset for Direct3D
<Hyperlink Foreground="{DynamicResource TextFillColorPrimaryBrush}" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/A-guide-to-FastFlags#exclusive-fullscreen">exclusive fullscreen</Hyperlink>
using Alt+Enter is already enabled by default.
</TextBlock>
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
@ -79,14 +77,14 @@
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" FontSize="14" Text="Framerate limit" /> <TextBlock Grid.Column="0" FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_FPSLimit_Title}" />
<TextBlock Grid.Column="1" Margin="4,0,0,0"> <TextBlock Grid.Column="1" Margin="4,0,0,0">
<Hyperlink TextDecorations="None" ToolTip="More information on this preset" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/A-guide-to-FastFlags#framerate-limit"> <Hyperlink TextDecorations="None" ToolTip="{x:Static resources:Strings.Menu_FastFlags_Presets_MoreInfo}" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/A-guide-to-FastFlags#framerate-limit">
<ui:SymbolIcon Symbol="QuestionCircle48" Margin="0,1,0,0" /> <ui:SymbolIcon Symbol="QuestionCircle48" Margin="0,1,0,0" />
</Hyperlink> </Hyperlink>
</TextBlock> </TextBlock>
</Grid> </Grid>
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Use a large number like 9999 for no limit. Set as 0 for defaults. " Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_FPSLimit_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:TextBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" Text="{Binding FramerateLimit, Mode=TwoWay}" PreviewTextInput="ValidateInt32" /> <ui:TextBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" Text="{Binding FramerateLimit, Mode=TwoWay}" PreviewTextInput="ValidateInt32" />
@ -94,11 +92,17 @@
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Preferred lighting technology" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_LightingTechnology_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose which lighting technology should be forced enabled in all games." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_LightingTechnology_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ComboBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" ItemsSource="{Binding LightingModes.Keys, Mode=OneTime}" Text="{Binding SelectedLightingMode, Mode=TwoWay}" /> <ComboBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" ItemsSource="{Binding LightingModes.Keys, Mode=OneTime}" Text="{Binding SelectedLightingMode, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=., Converter={StaticResource ResourceConverter}, ConverterParameter='Enums.FlagPresets.LightingMode.'}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</ui:CardControl> </ui:CardControl>
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
@ -108,17 +112,23 @@
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" FontSize="14" Text="Preferred escape menu version" /> <TextBlock Grid.Column="0" FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_EscapeMenuVersion_Title}" />
<TextBlock Grid.Column="1" Margin="4,0,0,0"> <TextBlock Grid.Column="1" Margin="4,0,0,0">
<Hyperlink TextDecorations="None" ToolTip="More information on this preset" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/A-guide-to-FastFlags#escape-menu-version"> <Hyperlink TextDecorations="None" ToolTip="{x:Static resources:Strings.Menu_FastFlags_Presets_MoreInfo}" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/A-guide-to-FastFlags#escape-menu-version">
<ui:SymbolIcon Symbol="QuestionCircle48" Margin="0,1,0,0" /> <ui:SymbolIcon Symbol="QuestionCircle48" Margin="0,1,0,0" />
</Hyperlink> </Hyperlink>
</TextBlock> </TextBlock>
</Grid> </Grid>
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose which version of the escape menu to use." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_EscapeMenuVersion_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ComboBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" ItemsSource="{Binding IGMenuVersions.Keys, Mode=OneTime}" Text="{Binding SelectedIGMenuVersion, Mode=TwoWay}" /> <ComboBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" ItemsSource="{Binding IGMenuVersions.Keys, Mode=OneTime}" Text="{Binding SelectedIGMenuVersion, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=., Converter={StaticResource ResourceConverter}, ConverterParameter='Enums.FlagPresets.InGameMenuVersion.'}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</ui:CardControl> </ui:CardControl>
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
@ -128,16 +138,14 @@
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" FontSize="14" Text="Enable ability to hide GUIs" /> <TextBlock Grid.Column="0" FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_HideGuis_Title}" />
<TextBlock Grid.Column="1" Margin="4,0,0,0"> <TextBlock Grid.Column="1" Margin="4,0,0,0">
<Hyperlink TextDecorations="None" ToolTip="More information on this preset" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/A-guide-to-FastFlags#gui-hiding"> <Hyperlink TextDecorations="None" ToolTip="{x:Static resources:Strings.Menu_FastFlags_Presets_MoreInfo}" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/A-guide-to-FastFlags#gui-hiding">
<ui:SymbolIcon Symbol="QuestionCircle48" Margin="0,1,0,0" /> <ui:SymbolIcon Symbol="QuestionCircle48" Margin="0,1,0,0" />
</Hyperlink> </Hyperlink>
</TextBlock> </TextBlock>
</Grid> </Grid>
<TextBlock Margin="0,2,0,0" FontSize="12" Foreground="{DynamicResource TextFillColorTertiaryBrush}"> <controls:MarkdownTextBlock Margin="0,2,0,0" FontSize="12" Foreground="{DynamicResource TextFillColorTertiaryBrush}" MarkdownText="{Binding HideGuisDescriptionText}"/>
Toggled with <Hyperlink Foreground="{DynamicResource TextFillColorPrimaryBrush}" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/A-guide-to-FastFlags#gui-hiding">keyboard shortcuts</Hyperlink>. Only works if you're in the <Hyperlink Foreground="{DynamicResource TextFillColorPrimaryBrush}" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://www.roblox.com/groups/32380007/Bloxstrap">Bloxstrap group</Hyperlink>.
</TextBlock>
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding GuiHidingEnabled, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding GuiHidingEnabled, Mode=TwoWay}" />
@ -150,26 +158,38 @@
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" FontSize="14" Text="Preferred materials" /> <TextBlock Grid.Column="0" FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_Materials_Title}" />
<TextBlock Grid.Column="1" Margin="4,0,0,0"> <TextBlock Grid.Column="1" Margin="4,0,0,0">
<Hyperlink TextDecorations="None" ToolTip="More information on this preset" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/A-guide-to-FastFlags#old-material-textures"> <Hyperlink TextDecorations="None" ToolTip="{x:Static resources:Strings.Menu_FastFlags_Presets_MoreInfo}" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/A-guide-to-FastFlags#old-material-textures">
<ui:SymbolIcon Symbol="QuestionCircle48" Margin="0,1,0,0" /> <ui:SymbolIcon Symbol="QuestionCircle48" Margin="0,1,0,0" />
</Hyperlink> </Hyperlink>
</TextBlock> </TextBlock>
</Grid> </Grid>
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose which material version should be forced in all games." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_Materials_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ComboBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" ItemsSource="{Binding MaterialVersions.Keys, Mode=OneTime}" Text="{Binding SelectedMaterialVersion, Mode=TwoWay}" /> <ComboBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" ItemsSource="{Binding MaterialVersions.Keys, Mode=OneTime}" Text="{Binding SelectedMaterialVersion, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=., Converter={StaticResource ResourceConverter}, ConverterParameter='Enums.FlagPresets.MaterialVersion.'}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</ui:CardControl> </ui:CardControl>
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Rendering mode" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_RenderingMode_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose what renderer Roblox should use. VR requires Direct3D/Automatic." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_RenderingMode_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ComboBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" ItemsSource="{Binding RenderingModes.Keys, Mode=OneTime}" Text="{Binding SelectedRenderingMode, Mode=TwoWay}" /> <ComboBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" ItemsSource="{Binding RenderingModes.Keys, Mode=OneTime}" Text="{Binding SelectedRenderingMode, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=., Converter={StaticResource ResourceConverter}, ConverterParameter='Enums.FlagPresets.RenderingMode.'}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</ui:CardControl> </ui:CardControl>
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
@ -179,14 +199,14 @@
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" FontSize="14" Text="Preserve rendering quality with display scaling" /> <TextBlock Grid.Column="0" FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_FixDisplayScaling_Title}" />
<TextBlock Grid.Column="1" Margin="4,0,0,0"> <TextBlock Grid.Column="1" Margin="4,0,0,0">
<Hyperlink TextDecorations="None" ToolTip="More information on this preset" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/A-guide-to-FastFlags#dpi-scaling-fixes"> <Hyperlink TextDecorations="None" ToolTip="{x:Static resources:Strings.Menu_FastFlags_Presets_MoreInfo}" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/A-guide-to-FastFlags#dpi-scaling-fixes">
<ui:SymbolIcon Symbol="QuestionCircle48" Margin="0,1,0,0" /> <ui:SymbolIcon Symbol="QuestionCircle48" Margin="0,1,0,0" />
</Hyperlink> </Hyperlink>
</TextBlock> </TextBlock>
</Grid> </Grid>
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Roblox reduces your rendering quality, depending on display scaling. This toggle disables that." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_FixDisplayScaling_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding FixDisplayScaling, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding FixDisplayScaling, Mode=TwoWay}" />
@ -194,8 +214,8 @@
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Use alternate graphics quality selector" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_AltGraphicsSelector_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Toggle between using the consolidated 1-10 / fine-grained 1-21 graphics quality slider." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_AltGraphicsSelector_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding AlternateGraphicsSelectorEnabled, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding AlternateGraphicsSelectorEnabled, Mode=TwoWay}" />

View File

@ -7,13 +7,14 @@
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Menu.Pages" xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Menu.Pages"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels" xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels"
xmlns:viewmodels="clr-namespace:Bloxstrap.UI.ViewModels.Menu" xmlns:viewmodels="clr-namespace:Bloxstrap.UI.ViewModels.Menu"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
d:DataContext="{d:DesignInstance Type=viewmodels:InstallationViewModel}" d:DataContext="{d:DesignInstance Type=viewmodels:InstallationViewModel}"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" d:DesignHeight="450" d:DesignWidth="800"
Title="InstallationPage"> Title="InstallationPage">
<StackPanel Margin="0,0,14,14"> <StackPanel Margin="0,0,14,14">
<TextBlock Text="Configure how Bloxstrap/Roblox is installed." FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <TextBlock Text="{x:Static resources:Strings.Menu_Installation_Description}" FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<ui:CardExpander Margin="0,16,0,0" IsExpanded="True"> <ui:CardExpander Margin="0,16,0,0" IsExpanded="True">
<ui:CardExpander.Style> <ui:CardExpander.Style>
@ -28,8 +29,8 @@
</ui:CardExpander.Style> </ui:CardExpander.Style>
<ui:CardExpander.Header> <ui:CardExpander.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Install Location" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Installation_InstallLocation_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose where Bloxstrap should be installed to." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Installation_InstallLocation_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardExpander.Header> </ui:CardExpander.Header>
<Grid> <Grid>
@ -39,8 +40,8 @@
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Margin="0,0,4,0" Text="{Binding InstallLocation, Mode=TwoWay}" /> <TextBox Grid.Column="0" Margin="0,0,4,0" Text="{Binding InstallLocation, Mode=TwoWay}" />
<ui:Button Grid.Column="1" Margin="4,0,4,0" Height="35" Icon="Folder24" Content="Browse" Command="{Binding BrowseInstallLocationCommand}" /> <ui:Button Grid.Column="1" Margin="4,0,4,0" Height="35" Icon="Folder24" Content="{x:Static resources:Strings.Common_Browse}" Command="{Binding BrowseInstallLocationCommand}" />
<ui:Button Grid.Column="2" Margin="4,0,0,0" Height="35" Icon="ArrowCounterclockwise24" Content="Reset" Command="{Binding ResetInstallLocationCommand}" /> <ui:Button Grid.Column="2" Margin="4,0,0,0" Height="35" Icon="ArrowCounterclockwise24" Content="{x:Static resources:Strings.Common_Reset}" Command="{Binding ResetInstallLocationCommand}" />
</Grid> </Grid>
</ui:CardExpander> </ui:CardExpander>
@ -63,15 +64,15 @@
<ui:CardAction Grid.Column="0" x:Name="OpenFolderCardAction" Margin="0,0,4,0" Icon="Folder24" Command="{Binding OpenFolderCommand}" > <ui:CardAction Grid.Column="0" x:Name="OpenFolderCardAction" Margin="0,0,4,0" Icon="Folder24" Command="{Binding OpenFolderCommand}" >
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Open Installation Folder" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Installation_OpenInstallFolder_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Where Bloxstrap is currently installed to." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Installation_OpenInstallFolder_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardAction> </ui:CardAction>
<ui:CardAction Grid.Column="1" Margin="4,0,0,0" Icon="UninstallApp24" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/Uninstalling-Bloxstrap"> <ui:CardAction Grid.Column="1" Margin="4,0,0,0" Icon="UninstallApp24" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/Uninstalling-Bloxstrap">
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Looking to uninstall?" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Installation_UninstallGuide_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Here's a guide on how to uninstall Bloxstrap." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Installation_UninstallGuide_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardAction> </ui:CardAction>
</Grid> </Grid>

View File

@ -6,14 +6,15 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels" xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="1080" d:DesignWidth="800" d:DesignHeight="1080" d:DesignWidth="800"
Title="IntegrationsPage" Title="IntegrationsPage"
Scrollable="True"> Scrollable="True">
<StackPanel Margin="0,0,14,14"> <StackPanel Margin="0,0,14,14">
<TextBlock Text="Configure quick and easy ways to improve the Roblox gameplay experience." FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <TextBlock Text="{x:Static resources:Strings.Menu_Integrations_Description}" FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<TextBlock Text="Activity tracking" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" /> <TextBlock Text="{x:Static resources:Strings.Menu_Integrations_ActivityTracking}" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
@ -22,14 +23,14 @@
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" FontSize="14" Text="Enable activity tracking" /> <TextBlock Grid.Column="0" FontSize="14" Text="{x:Static resources:Strings.Menu_Integrations_EnableActivityTracking_Title}" />
<TextBlock Grid.Column="1" Margin="4,0,0,0"> <TextBlock Grid.Column="1" Margin="4,0,0,0">
<Hyperlink TextDecorations="None" ToolTip="More information on this integration" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/What-is-activity-tracking%3F"> <Hyperlink TextDecorations="None" ToolTip="{x:Static resources:Strings.Menu_Integrations_MoreInfo}" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/What-is-activity-tracking%3F">
<ui:SymbolIcon Symbol="QuestionCircle48" Margin="0,1,0,0" /> <ui:SymbolIcon Symbol="QuestionCircle48" Margin="0,1,0,0" />
</Hyperlink> </Hyperlink>
</TextBlock> </TextBlock>
</Grid> </Grid>
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Allows for Bloxstrap to detect what Roblox game you're playing. Certain features may require this." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Integrations_EnableActivityTracking_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch x:Name="ActivityTrackingEnabledToggle" IsChecked="{Binding ActivityTrackingEnabled, Mode=TwoWay}" /> <ui:ToggleSwitch x:Name="ActivityTrackingEnabledToggle" IsChecked="{Binding ActivityTrackingEnabled, Mode=TwoWay}" />
@ -37,20 +38,20 @@
<ui:CardControl Margin="0,8,0,0" IsEnabled="{Binding IsChecked, ElementName=ActivityTrackingEnabledToggle, Mode=OneWay}"> <ui:CardControl Margin="0,8,0,0" IsEnabled="{Binding IsChecked, ElementName=ActivityTrackingEnabledToggle, Mode=OneWay}">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="See server location when joining a game" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Integrations_ShowServerDetails_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="When you join a game, you'll be notified of where your server's located. Won't show in fullscreen." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Integrations_ShowServerDetails_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding ShowServerDetailsEnabled, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding ShowServerDetailsEnabled, Mode=TwoWay}" />
</ui:CardControl> </ui:CardControl>
<TextBlock Text="Discord Rich Presence" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" /> <TextBlock Text="{x:Static resources:Strings.Common_DiscordRichPresence}" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
<TextBlock Margin="0,4,0,0" Text="This feature requires activity tracking to be enabled." TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <TextBlock Margin="0,4,0,0" Text="{x:Static resources:Strings.Menu_Integrations_RequiresActivityTracking}" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<ui:CardControl Margin="0,8,0,0" IsEnabled="{Binding IsChecked, ElementName=ActivityTrackingEnabledToggle, Mode=OneWay}"> <ui:CardControl Margin="0,8,0,0" IsEnabled="{Binding IsChecked, ElementName=ActivityTrackingEnabledToggle, Mode=OneWay}">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Show game activity" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Integrations_ShowGameActivity_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="When playing a Roblox game, the game you're playing will show on your Discord profile activity." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Integrations_ShowGameActivity_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch x:Name="DiscordActivityEnabledToggle" IsChecked="{Binding DiscordActivityEnabled, Mode=TwoWay}" /> <ui:ToggleSwitch x:Name="DiscordActivityEnabledToggle" IsChecked="{Binding DiscordActivityEnabled, Mode=TwoWay}" />
@ -58,26 +59,26 @@
<ui:CardControl Margin="0,8,0,0" IsEnabled="{Binding IsChecked, ElementName=DiscordActivityEnabledToggle, Mode=OneWay}"> <ui:CardControl Margin="0,8,0,0" IsEnabled="{Binding IsChecked, ElementName=DiscordActivityEnabledToggle, Mode=OneWay}">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Allow activity joining" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Integrations_AllowActivityJoining_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Allows for anybody to join the game you're currently in through your Discord profile." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Integrations_AllowActivityJoining_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding DiscordActivityJoinEnabled, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding DiscordActivityJoinEnabled, Mode=TwoWay}" />
</ui:CardControl> </ui:CardControl>
<TextBlock Text="Miscellaneous" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" /> <TextBlock Text="{x:Static resources:Strings.Common_Miscellaneous}" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Allow multi-instance launching" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Integrations_AllowMultipleInstances_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Allows for having more than one Roblox game client instance open simultaneously." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Integrations_AllowMultipleInstances_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding MultiInstanceLaunchingEnabled, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding MultiInstanceLaunchingEnabled, Mode=TwoWay}" />
</ui:CardControl> </ui:CardControl>
<TextBlock Text="Custom Integrations" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" /> <TextBlock Text="{x:Static resources:Strings.Menu_Integrations_Custom_Title}" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
<TextBlock Margin="0,4,0,0" Text="Here, you can have other programs launch with Roblox automatically." TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <TextBlock Margin="0,4,0,0" Text="{x:Static resources:Strings.Menu_Integrations_Custom_Description}" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<Grid Margin="0,8,0,0"> <Grid Margin="0,8,0,0">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="*" /> <RowDefinition Height="*" />
@ -93,8 +94,8 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<ui:Button Grid.Column="0" Margin="0,0,4,0" Icon="Add28" Content="New" HorizontalAlignment="Stretch" Command="{Binding AddIntegrationCommand, Mode=OneTime}" /> <ui:Button Grid.Column="0" Margin="0,0,4,0" Icon="Add28" Content="{x:Static resources:Strings.Common_New}" HorizontalAlignment="Stretch" Command="{Binding AddIntegrationCommand, Mode=OneTime}" />
<ui:Button Grid.Column="1" Margin="4,0,0,0" Icon="Delete28" Content="Delete" HorizontalAlignment="Stretch" Appearance="Danger" IsEnabled="{Binding IsCustomIntegrationSelected, Mode=OneWay}" Command="{Binding DeleteIntegrationCommand, Mode=OneTime}" /> <ui:Button Grid.Column="1" Margin="4,0,0,0" Icon="Delete28" Content="{x:Static resources:Strings.Common_Delete}" HorizontalAlignment="Stretch" Appearance="Danger" IsEnabled="{Binding IsCustomIntegrationSelected, Mode=OneWay}" Command="{Binding DeleteIntegrationCommand, Mode=OneTime}" />
</Grid> </Grid>
<StackPanel Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Margin="4,0,0,0"> <StackPanel Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Margin="4,0,0,0">
<StackPanel.Style> <StackPanel.Style>
@ -106,15 +107,15 @@
</Style.Triggers> </Style.Triggers>
</Style> </Style>
</StackPanel.Style> </StackPanel.Style>
<TextBlock Text="Name" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <TextBlock Text="{x:Static resources:Strings.Common_Name}" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<ui:TextBox Margin="0,4,0,0" Text="{Binding SelectedCustomIntegration.Name}" /> <ui:TextBox Margin="0,4,0,0" Text="{Binding SelectedCustomIntegration.Name}" />
<TextBlock Margin="0,8,0,0" Text="Application Location" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <TextBlock Margin="0,8,0,0" Text="{x:Static resources:Strings.Menu_Integrations_Custom_AppLocation}" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<ui:TextBox Margin="0,4,0,0" PlaceholderText="e.g. C:\Windows\System32\cmd.exe" Text="{Binding SelectedCustomIntegration.Location}" /> <ui:TextBox Margin="0,4,0,0" PlaceholderText="{x:Static resources:Strings.Menu_Integrations_Custom_AppLocation_Placeholder}" Text="{Binding SelectedCustomIntegration.Location}" />
<TextBlock Margin="0,8,0,0" Text="Launch Args" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <TextBlock Margin="0,8,0,0" Text="{x:Static resources:Strings.Menu_Integrations_Custom_LaunchArgs}" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<ui:TextBox Margin="0,4,0,0" PlaceholderText="e.g. /k echo Roblox is running!" Text="{Binding SelectedCustomIntegration.LaunchArgs}" /> <ui:TextBox Margin="0,4,0,0" PlaceholderText="{x:Static resources:Strings.Menu_Integrations_Custom_LaunchArgs_Placeholder}" Text="{Binding SelectedCustomIntegration.LaunchArgs}" />
<CheckBox Margin="0,8,0,0" Content="Auto close when Roblox closes" IsChecked="{Binding SelectedCustomIntegration.AutoClose}" /> <CheckBox Margin="0,8,0,0" Content="{x:Static resources:Strings.Menu_Integrations_Custom_AutoClose}" IsChecked="{Binding SelectedCustomIntegration.AutoClose}" />
</StackPanel> </StackPanel>
<TextBlock Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Text="No integration selected, please select or add a new one" VerticalAlignment="Center" HorizontalAlignment="Center"> <TextBlock Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Text="{x:Static resources:Strings.Menu_Integrations_Custom_NoneSelected}" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock.Style> <TextBlock.Style>
<Style> <Style>
<Style.Triggers> <Style.Triggers>

View File

@ -5,12 +5,14 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels" xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
xmlns:controls="clr-namespace:Bloxstrap.ControlsWpf"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="800" d:DesignWidth="800" d:DesignHeight="800" d:DesignWidth="800"
Title="ModsPage" Title="ModsPage"
Scrollable="True"> Scrollable="True">
<StackPanel Margin="0,0,14,14"> <StackPanel Margin="0,0,14,14">
<TextBlock Text="Manage and apply file mods to the Roblox game client." FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <TextBlock Text="{x:Static resources:Strings.Menu_Mods_Description}" FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<Grid Margin="0,16,0,0"> <Grid Margin="0,16,0,0">
<Grid.RowDefinitions> <Grid.RowDefinitions>
@ -23,7 +25,7 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<ui:CardAction Grid.Row="0" Grid.Column="0" x:Name="OpenModFolderCardAction" Margin="0,0,4,0" Icon="Folder24" Command="{Binding OpenModsFolderCommand}" IsEnabled="{Binding Source={x:Static models:GlobalViewModel.IsNotFirstRun}, Mode=OneTime}"> <ui:CardAction Grid.Row="0" Grid.Column="0" x:Name="OpenModFolderCardAction" Margin="0,0,4,0" Icon="Folder24" Command="{Binding OpenModsFolderCommand}" IsEnabled="{Binding Source={x:Static models:GlobalViewModel.IsNotFirstRun}, Mode=OneTime}">
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Open Mods Folder"> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_OpenModsFolder_Title}">
<!--this is so fucking stupid the disabled state of the cardaction doesnt change the header text colour--> <!--this is so fucking stupid the disabled state of the cardaction doesnt change the header text colour-->
<TextBlock.Style> <TextBlock.Style>
<Style> <Style>
@ -39,11 +41,11 @@
<TextBlock Margin="0,2,0,0" FontSize="12" Foreground="{DynamicResource TextFillColorTertiaryBrush}"> <TextBlock Margin="0,2,0,0" FontSize="12" Foreground="{DynamicResource TextFillColorTertiaryBrush}">
<TextBlock.Style> <TextBlock.Style>
<Style> <Style>
<Setter Property="TextBlock.Text" Value="Manage custom Roblox mods here."/> <Setter Property="TextBlock.Text" Value="{x:Static resources:Strings.Menu_Mods_OpenModsFolder_Description}"/>
<Style.Triggers> <Style.Triggers>
<DataTrigger Binding="{Binding ElementName=OpenModFolderCardAction, Path=IsEnabled, Mode=OneTime}" Value="False"> <DataTrigger Binding="{Binding ElementName=OpenModFolderCardAction, Path=IsEnabled, Mode=OneTime}" Value="False">
<Setter Property="TextBlock.Foreground" Value="{DynamicResource TextFillColorDisabledBrush}" /> <Setter Property="TextBlock.Foreground" Value="{DynamicResource TextFillColorDisabledBrush}" />
<Setter Property="TextBlock.Text" Value="Bloxstrap must first be installed." /> <Setter Property="TextBlock.Text" Value="{x:Static resources:Strings.Menu_Mods_OpenModsFolder_MustBeInstalled}" />
</DataTrigger> </DataTrigger>
</Style.Triggers> </Style.Triggers>
</Style> </Style>
@ -53,19 +55,19 @@
</ui:CardAction> </ui:CardAction>
<ui:CardAction Grid.Row="0" Grid.Column="1" Margin="4,0,0,0" Icon="BookQuestionMark24" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/Adding-custom-mods"> <ui:CardAction Grid.Row="0" Grid.Column="1" Margin="4,0,0,0" Icon="BookQuestionMark24" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://github.com/pizzaboxer/bloxstrap/wiki/Adding-custom-mods">
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Help" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Common_Help}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="See info about managing and creating mods." Padding="0,0,16,0" Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Mods_Help_Description}" Padding="0,0,16,0" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardAction> </ui:CardAction>
</Grid> </Grid>
<TextBlock Text="Presets" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" /> <TextBlock Text="{x:Static resources:Strings.Common_Presets}" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Use old death sound" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_Presets_OldDeathSound_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Bring back the classic 'oof' death sound." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Mods_Presets_OldDeathSound_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding OldDeathSoundEnabled, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding OldDeathSoundEnabled, Mode=TwoWay}" />
@ -74,18 +76,24 @@
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Mouse cursor" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_Presets_MouseCursor_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose between using two classic Roblox cursor styles." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Mods_Presets_MouseCursor_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ComboBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" ItemsSource="{Binding CursorTypes.Keys, Mode=OneTime}" Text="{Binding SelectedCursorType, Mode=TwoWay}" /> <ComboBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" ItemsSource="{Binding CursorTypes, Mode=OneTime}" Text="{Binding SelectedCursorType, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=., Converter={StaticResource ResourceConverter}, ConverterParameter='Enums.CursorType.'}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</ui:CardControl> </ui:CardControl>
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Use old avatar editor background" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_Presets_OldAvatarEditor_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Bring back the old avatar editor background used in the Roblox app prior to 2020." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Mods_Presets_OldAvatarEditor_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding OldAvatarBackground, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding OldAvatarBackground, Mode=TwoWay}" />
@ -94,8 +102,8 @@
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Emulate old character sounds" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_Presets_OldCharacterSounds_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="An attempt to roughly bring back the character sounds used prior to 2014." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Mods_Presets_OldCharacterSounds_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding OldCharacterSoundsEnabled, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding OldCharacterSoundsEnabled, Mode=TwoWay}" />
@ -104,8 +112,8 @@
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Disable desktop app" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_Presets_DisableDesktopApp_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Stops the desktop app from showing, especially when you leave a game." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Mods_Presets_DisableDesktopApp_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding DisableAppPatchEnabled, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding DisableAppPatchEnabled, Mode=TwoWay}" />
@ -114,35 +122,37 @@
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Preferred emoji type" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_Presets_EmojiType_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose which type of emoji should Roblox use." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Mods_Presets_EmojiType_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ComboBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" ItemsSource="{Binding EmojiTypes.Keys, Mode=OneTime}" Text="{Binding SelectedEmojiType, Mode=TwoWay}" /> <ComboBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" ItemsSource="{Binding EmojiTypes, Mode=OneTime}" Text="{Binding SelectedEmojiType, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=., Converter={StaticResource ResourceConverter}, ConverterParameter='Enums.EmojiType.'}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</ui:CardControl> </ui:CardControl>
<TextBlock Text="Miscellaneous" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" /> <TextBlock Text="{x:Static resources:Strings.Common_Miscellaneous}" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
<ui:CardControl Margin="0,8,0,0"> <ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Apply custom font" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_Misc_CustomFont_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Foreground="{DynamicResource TextFillColorTertiaryBrush}"> <TextBlock Margin="0,2,0,0" FontSize="12" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{x:Static resources:Strings.Menu_Mods_Misc_CustomFont_Description}" />
Forces every in-game font to be a font that you choose.
</TextBlock>
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<StackPanel> <StackPanel>
<ui:Button Icon="DocumentAdd16" Content="Choose font..." Command="{Binding ManageCustomFontCommand}" Visibility="{Binding ChooseCustomFontVisibility, Mode=OneWay}" /> <ui:Button Icon="DocumentAdd16" Content="{x:Static resources:Strings.Menu_Mods_Misc_CustomFont_Choose}" Command="{Binding ManageCustomFontCommand}" Visibility="{Binding ChooseCustomFontVisibility, Mode=OneWay}" />
<ui:Button Icon="Delete16" Content="Remove applied font" Appearance="Danger" Command="{Binding ManageCustomFontCommand}" Visibility="{Binding DeleteCustomFontVisibility, Mode=OneWay}" /> <ui:Button Icon="Delete16" Content="{x:Static resources:Strings.Menu_Mods_Misc_CustomFont_Remove}" Appearance="Danger" Command="{Binding ManageCustomFontCommand}" Visibility="{Binding DeleteCustomFontVisibility, Mode=OneWay}" />
</StackPanel> </StackPanel>
</ui:CardControl> </ui:CardControl>
<ui:CardControl x:Name="FullscreenOptimizationsToggle" Margin="0,8,0,0"> <ui:CardControl x:Name="FullscreenOptimizationsToggle" Margin="0,8,0,0">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel> <StackPanel>
<TextBlock FontSize="14" Text="Disable fullscreen optimizations" /> <TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_Misc_DisableFullscreenOptimisations_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Foreground="{DynamicResource TextFillColorTertiaryBrush}"> <controls:MarkdownTextBlock Margin="0,2,0,0" FontSize="12" Foreground="{DynamicResource TextFillColorTertiaryBrush}" MarkdownText="{Binding DisableFullscreenOptimisationsDescriptionText, Mode=OneTime}"/>
A Windows feature that intends to improve fullscreen performance. <Hyperlink Foreground="{DynamicResource TextFillColorPrimaryBrush}" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://devblogs.microsoft.com/directx/demystifying-full-screen-optimizations/">See here for more information</Hyperlink>.
</TextBlock>
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding DisableFullscreenOptimizations, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding DisableFullscreenOptimizations, Mode=TwoWay}" />

View File

@ -6,6 +6,8 @@
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Menu.Pages" xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Menu.Pages"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels" xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
xmlns:controls="clr-namespace:Bloxstrap.ControlsWpf"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" d:DesignHeight="450" d:DesignWidth="800"
Title="PreInstallPage" Title="PreInstallPage"
@ -22,22 +24,15 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,0,16" Text="There's just a few things you first should know about." FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,0,16" Text="{x:Static resources:Strings.Menu_PreInstall_Description}" FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<Border Grid.Row="1" Grid.Column="0" Margin="0,0,16,0" BorderThickness="1" BorderBrush="{DynamicResource TextFillColorPrimaryBrush}"> <Border Grid.Row="1" Grid.Column="0" Margin="0,0,16,0" BorderThickness="1" BorderBrush="{DynamicResource TextFillColorPrimaryBrush}">
<Image RenderOptions.BitmapScalingMode="HighQuality" Source="pack://application:,,,/Resources/Menu/StartMenu.png" /> <Image RenderOptions.BitmapScalingMode="HighQuality" Source="pack://application:,,,/Resources/Menu/StartMenu.png" />
</Border> </Border>
<StackPanel Grid.Row="1" Grid.Column="1"> <StackPanel Grid.Row="1" Grid.Column="1">
<TextBlock FontSize="14" TextWrapping="Wrap" Text="After installation has finished, the Bloxstrap Menu will be registered as an application in the Start menu. If you ever need to access it again to re-adjust your settings, or access resources such as FastFlag management, you can find it there." /> <TextBlock FontSize="14" TextWrapping="Wrap" Text="{x:Static resources:Strings.Menu_PreInstall_Info_1}" />
<TextBlock Margin="0,16,0,0" FontSize="14" TextWrapping="Wrap"> <controls:MarkdownTextBlock Margin="0,16,0,0" FontSize="14" TextWrapping="Wrap" MarkdownText="{Binding Info2Text, Mode=OneTime}" />
If you ever need help or guidance with anything, be sure to check the
<Hyperlink Foreground="{DynamicResource TextFillColorPrimaryBrush}" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://www.github.com/pizzaboxer/bloxstrap/wiki">Wiki</Hyperlink>.
If you still need something, open an
<Hyperlink Foreground="{DynamicResource TextFillColorPrimaryBrush}" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://www.github.com/pizzaboxer/bloxstrap/issues">issue</Hyperlink>
on GitHub, or join our
<Hyperlink Foreground="{DynamicResource TextFillColorPrimaryBrush}" Command="models:GlobalViewModel.OpenWebpageCommand" CommandParameter="https://discord.gg/nKjV3mGq6R">Discord server</Hyperlink>.
</TextBlock>
</StackPanel> </StackPanel>
</Grid> </Grid>
</ui:UiPage> </ui:UiPage>

View File

@ -1,4 +1,6 @@
namespace Bloxstrap.UI.Elements.Menu.Pages using Bloxstrap.UI.ViewModels.Menu;
namespace Bloxstrap.UI.Elements.Menu.Pages
{ {
/// <summary> /// <summary>
/// Interaction logic for PreInstallPage.xaml /// Interaction logic for PreInstallPage.xaml
@ -7,6 +9,7 @@
{ {
public PreInstallPage() public PreInstallPage()
{ {
DataContext = new PreInstallViewModel();
InitializeComponent(); InitializeComponent();
} }
} }

View File

@ -11,9 +11,11 @@ namespace Bloxstrap.UI.ViewModels.ContextMenu
private readonly ActivityWatcher _activityWatcher; private readonly ActivityWatcher _activityWatcher;
public string InstanceId => _activityWatcher.ActivityJobId; public string InstanceId => _activityWatcher.ActivityJobId;
public string ServerType => $"{_activityWatcher.ActivityServerType} server"; public string ServerType => string.Format(
public string ServerLocation { get; private set; } = "Loading, please wait..."; Resources.Strings.ContextMenu_ServerInformation_TypeFormat,
public string UdmuxProxied => _activityWatcher.ActivityMachineUDMUX ? "Yes" : "No"; Resources.Strings.ResourceManager.GetStringSafe($"Enums.ServerType.{_activityWatcher.ActivityServerType}"));
public string ServerLocation { get; private set; } = Resources.Strings.ContextMenu_ServerInformation_Loading;
public string UdmuxProxied => _activityWatcher.ActivityMachineUDMUX ? Resources.Strings.Common_Yes : Resources.Strings.Common_No;
public ICommand CopyInstanceIdCommand => new RelayCommand(CopyInstanceId); public ICommand CopyInstanceIdCommand => new RelayCommand(CopyInstanceId);
public ICommand CloseWindowCommand => new RelayCommand(_window.Close); public ICommand CloseWindowCommand => new RelayCommand(_window.Close);

View File

@ -4,7 +4,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
{ {
public class AboutViewModel public class AboutViewModel
{ {
public string Version => $"Version {App.Version}"; public string Version => string.Format(Resources.Strings.Menu_About_Version, App.Version);
public BuildMetadataAttribute BuildMetadata => App.BuildMetadata; public BuildMetadataAttribute BuildMetadata => App.BuildMetadata;

View File

@ -35,7 +35,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
{ {
var dialog = new OpenFileDialog var dialog = new OpenFileDialog
{ {
Filter = "Icon files|*.ico|All files|*.*" Filter = $"{Resources.Strings.Menu_IconFiles}|*.ico|{Resources.Strings.Menu_AllFiles}|*.*"
}; };
if (dialog.ShowDialog() != true) if (dialog.ShowDialog() != true)
@ -50,58 +50,58 @@ namespace Bloxstrap.UI.ViewModels.Menu
_page = page; _page = page;
} }
public IReadOnlyDictionary<string, Theme> Themes { get; set; } = new Dictionary<string, Theme>() public IReadOnlyCollection<Theme> Themes { get; set; } = new Theme[]
{ {
{ "System Default", Enums.Theme.Default }, Theme.Default,
{ "Light", Enums.Theme.Light }, Theme.Light,
{ "Dark", Enums.Theme.Dark }, Theme.Dark
}; };
public string Theme public Theme Theme
{ {
get => Themes.FirstOrDefault(x => x.Value == App.Settings.Prop.Theme).Key; get => App.Settings.Prop.Theme;
set set
{ {
App.Settings.Prop.Theme = Themes[value]; App.Settings.Prop.Theme = value;
((MainWindow)Window.GetWindow(_page)!).ApplyTheme(); ((MainWindow)Window.GetWindow(_page)!).ApplyTheme();
} }
} }
public IReadOnlyDictionary<string, BootstrapperStyle> Dialogs { get; set; } = new Dictionary<string, BootstrapperStyle>() public IReadOnlyCollection<BootstrapperStyle> Dialogs { get; set; } = new BootstrapperStyle[]
{ {
{ "Fluent", BootstrapperStyle.FluentDialog }, BootstrapperStyle.FluentDialog,
{ "Progress (~2014)", BootstrapperStyle.ProgressDialog }, BootstrapperStyle.ProgressDialog,
{ "Legacy (2011 - 2014)", BootstrapperStyle.LegacyDialog2011 }, BootstrapperStyle.LegacyDialog2011,
{ "Legacy (2008 - 2011)", BootstrapperStyle.LegacyDialog2008 }, BootstrapperStyle.LegacyDialog2008,
{ "Vista (2008 - 2011)", BootstrapperStyle.VistaDialog }, BootstrapperStyle.VistaDialog,
{ "Fake Byfron (2023)", BootstrapperStyle.ByfronDialog }, BootstrapperStyle.ByfronDialog
}; };
public string Dialog public BootstrapperStyle Dialog
{ {
get => Dialogs.FirstOrDefault(x => x.Value == App.Settings.Prop.BootstrapperStyle).Key; get => App.Settings.Prop.BootstrapperStyle;
set => App.Settings.Prop.BootstrapperStyle = Dialogs[value]; set => App.Settings.Prop.BootstrapperStyle = value;
} }
public IReadOnlyDictionary<string, BootstrapperIcon> Icons { get; set; } = new Dictionary<string, BootstrapperIcon>() public IReadOnlyCollection<BootstrapperIcon> Icons { get; set; } = new BootstrapperIcon[]
{ {
{ "Bloxstrap", BootstrapperIcon.IconBloxstrap }, BootstrapperIcon.IconBloxstrap,
{ "2022", BootstrapperIcon.Icon2022 }, BootstrapperIcon.Icon2022,
{ "2019", BootstrapperIcon.Icon2019 }, BootstrapperIcon.Icon2019,
{ "2017", BootstrapperIcon.Icon2017 }, BootstrapperIcon.Icon2017,
{ "Late 2015", BootstrapperIcon.IconLate2015 }, BootstrapperIcon.IconLate2015,
{ "Early 2015", BootstrapperIcon.IconEarly2015 }, BootstrapperIcon.IconEarly2015,
{ "2011", BootstrapperIcon.Icon2011 }, BootstrapperIcon.Icon2011,
{ "2008", BootstrapperIcon.Icon2008 }, BootstrapperIcon.Icon2008,
{ "Custom", BootstrapperIcon.IconCustom }, BootstrapperIcon.IconCustom
}; };
public string Icon public BootstrapperIcon Icon
{ {
get => Icons.FirstOrDefault(x => x.Value == App.Settings.Prop.BootstrapperIcon).Key; get => App.Settings.Prop.BootstrapperIcon;
set set
{ {
App.Settings.Prop.BootstrapperIcon = Icons[value]; App.Settings.Prop.BootstrapperIcon = value;
OnPropertyChanged(nameof(IconPreviewSource)); OnPropertyChanged(nameof(IconPreviewSource));
} }
} }

View File

@ -17,7 +17,7 @@
ShowLoadingError = false; ShowLoadingError = false;
OnPropertyChanged(nameof(ShowLoadingError)); OnPropertyChanged(nameof(ShowLoadingError));
ChannelInfoLoadingText = "Fetching latest deploy info, please wait..."; ChannelInfoLoadingText = Resources.Strings.Menu_Behaviour_Channel_Fetching;
OnPropertyChanged(nameof(ChannelInfoLoadingText)); OnPropertyChanged(nameof(ChannelInfoLoadingText));
ChannelDeployInfo = null; ChannelDeployInfo = null;
@ -46,8 +46,8 @@
ChannelInfoLoadingText = ex.ResponseMessage.StatusCode switch ChannelInfoLoadingText = ex.ResponseMessage.StatusCode switch
{ {
HttpStatusCode.NotFound => "The specified channel name does not exist.", HttpStatusCode.NotFound => Resources.Strings.Menu_Behaviour_Channel_DoesNotExist,
_ => $"Failed to fetch information! (HTTP {(int)ex.ResponseMessage.StatusCode} - {ex.ResponseMessage.ReasonPhrase})", _ => $"{Resources.Strings.Menu_Behaviour_Channel_FetchFailed} (HTTP {(int)ex.ResponseMessage.StatusCode} - {ex.ResponseMessage.ReasonPhrase})",
}; };
OnPropertyChanged(nameof(ChannelInfoLoadingText)); OnPropertyChanged(nameof(ChannelInfoLoadingText));
} }
@ -59,7 +59,7 @@
ShowLoadingError = true; ShowLoadingError = true;
OnPropertyChanged(nameof(ShowLoadingError)); OnPropertyChanged(nameof(ShowLoadingError));
ChannelInfoLoadingText = $"Failed to fetch information! ({ex.Message})"; ChannelInfoLoadingText = $"{Resources.Strings.Menu_Behaviour_Channel_FetchFailed} ({ex.Message})";
OnPropertyChanged(nameof(ChannelInfoLoadingText)); OnPropertyChanged(nameof(ChannelInfoLoadingText));
} }
} }
@ -93,18 +93,17 @@
} }
} }
// todo - move to enum attributes? public IReadOnlyCollection<ChannelChangeMode> ChannelChangeModes => new ChannelChangeMode[]
public IReadOnlyDictionary<string, ChannelChangeMode> ChannelChangeModes => new Dictionary<string, ChannelChangeMode>
{ {
{ "Change automatically", ChannelChangeMode.Automatic }, ChannelChangeMode.Automatic,
{ "Always prompt", ChannelChangeMode.Prompt }, ChannelChangeMode.Prompt,
{ "Never change", ChannelChangeMode.Ignore }, ChannelChangeMode.Ignore,
}; };
public string SelectedChannelChangeMode public ChannelChangeMode SelectedChannelChangeMode
{ {
get => ChannelChangeModes.FirstOrDefault(x => x.Value == App.Settings.Prop.ChannelChangeMode).Key; get => App.Settings.Prop.ChannelChangeMode;
set => App.Settings.Prop.ChannelChangeMode = ChannelChangeModes[value]; set => App.Settings.Prop.ChannelChangeMode = value;
} }
public bool ForceRobloxReinstallation public bool ForceRobloxReinstallation

View File

@ -7,6 +7,7 @@ using Wpf.Ui.Mvvm.Contracts;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using Bloxstrap.UI.Elements.Menu.Pages; using Bloxstrap.UI.Elements.Menu.Pages;
using Bloxstrap.Enums.FlagPresets;
namespace Bloxstrap.UI.ViewModels.Menu namespace Bloxstrap.UI.ViewModels.Menu
{ {
@ -58,9 +59,9 @@ namespace Bloxstrap.UI.ViewModels.Menu
set => App.FastFlags.SetPreset("Rendering.Framerate", value); set => App.FastFlags.SetPreset("Rendering.Framerate", value);
} }
public IReadOnlyDictionary<string, string> RenderingModes => FastFlagManager.RenderingModes; public IReadOnlyDictionary<RenderingMode, string> RenderingModes => FastFlagManager.RenderingModes;
public string SelectedRenderingMode public RenderingMode SelectedRenderingMode
{ {
get => App.FastFlags.GetPresetEnum(RenderingModes, "Rendering.Mode", "True"); get => App.FastFlags.GetPresetEnum(RenderingModes, "Rendering.Mode", "True");
set set
@ -82,15 +83,15 @@ namespace Bloxstrap.UI.ViewModels.Menu
set => App.FastFlags.SetPreset("UI.Menu.GraphicsSlider", value ? "True" : null); set => App.FastFlags.SetPreset("UI.Menu.GraphicsSlider", value ? "True" : null);
} }
public IReadOnlyDictionary<string, string> MaterialVersions => FastFlagManager.MaterialVersions; public IReadOnlyDictionary<MaterialVersion, string> MaterialVersions => FastFlagManager.MaterialVersions;
public string SelectedMaterialVersion public MaterialVersion SelectedMaterialVersion
{ {
get get
{ {
string oldMaterials = App.FastFlags.GetPresetEnum(MaterialVersions, "Rendering.Materials", FastFlagManager.OldTexturesFlagValue); MaterialVersion oldMaterials = App.FastFlags.GetPresetEnum(MaterialVersions, "Rendering.Materials", FastFlagManager.OldTexturesFlagValue);
if (oldMaterials != "Chosen by game") if (oldMaterials != MaterialVersion.Default)
return oldMaterials; return oldMaterials;
return App.FastFlags.GetPresetEnum(MaterialVersions, "Rendering.Materials", FastFlagManager.NewTexturesFlagValue); return App.FastFlags.GetPresetEnum(MaterialVersions, "Rendering.Materials", FastFlagManager.NewTexturesFlagValue);
@ -99,9 +100,9 @@ namespace Bloxstrap.UI.ViewModels.Menu
set => App.FastFlags.SetPresetEnum("Rendering.Materials", MaterialVersions[value], MaterialVersions[value] == "NewTexturePack" ? FastFlagManager.OldTexturesFlagValue : FastFlagManager.NewTexturesFlagValue); set => App.FastFlags.SetPresetEnum("Rendering.Materials", MaterialVersions[value], MaterialVersions[value] == "NewTexturePack" ? FastFlagManager.OldTexturesFlagValue : FastFlagManager.NewTexturesFlagValue);
} }
public IReadOnlyDictionary<string, Dictionary<string, string?>> IGMenuVersions => FastFlagManager.IGMenuVersions; public IReadOnlyDictionary<InGameMenuVersion, Dictionary<string, string?>> IGMenuVersions => FastFlagManager.IGMenuVersions;
public string SelectedIGMenuVersion public InGameMenuVersion SelectedIGMenuVersion
{ {
get get
{ {
@ -133,9 +134,9 @@ namespace Bloxstrap.UI.ViewModels.Menu
} }
} }
public IReadOnlyDictionary<string, string> LightingModes => FastFlagManager.LightingModes; public IReadOnlyDictionary<LightingMode, string> LightingModes => FastFlagManager.LightingModes;
public string SelectedLightingMode public LightingMode SelectedLightingMode
{ {
get => App.FastFlags.GetPresetEnum(LightingModes, "Rendering.Lighting", "True"); get => App.FastFlags.GetPresetEnum(LightingModes, "Rendering.Lighting", "True");
set => App.FastFlags.SetPresetEnum("Rendering.Lighting", LightingModes[value], "True"); set => App.FastFlags.SetPresetEnum("Rendering.Lighting", LightingModes[value], "True");
@ -146,5 +147,20 @@ namespace Bloxstrap.UI.ViewModels.Menu
get => App.FastFlags.GetPreset("UI.Hide") == "32380007"; get => App.FastFlags.GetPreset("UI.Hide") == "32380007";
set => App.FastFlags.SetPreset("UI.Hide", value ? "32380007" : null); set => App.FastFlags.SetPreset("UI.Hide", value ? "32380007" : null);
} }
public string Direct3DExclusiveFullscreenInfoText
{
get => string.Format(
Resources.Strings.Menu_FastFlags_Presets_D3DExclusiveFullscreenInfo,
"https://github.com/pizzaboxer/bloxstrap/wiki/A-guide-to-FastFlags#exclusive-fullscreen");
}
public string HideGuisDescriptionText
{
get => string.Format(
Resources.Strings.Menu_FastFlags_Presets_HideGuis_Description,
"https://github.com/pizzaboxer/bloxstrap/wiki/A-guide-to-FastFlags#gui-hiding",
"https://www.roblox.com/groups/32380007/Bloxstrap");
}
} }
} }

View File

@ -14,7 +14,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
{ {
CustomIntegrations.Add(new CustomIntegration() CustomIntegrations.Add(new CustomIntegration()
{ {
Name = "New Integration" Name = Resources.Strings.Menu_Integrations_Custom_NewIntegration
}); });
SelectedCustomIntegrationIndex = CustomIntegrations.Count - 1; SelectedCustomIntegrationIndex = CustomIntegrations.Count - 1;

View File

@ -19,7 +19,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
public ICommand ConfirmSettingsCommand => new RelayCommand(ConfirmSettings); public ICommand ConfirmSettingsCommand => new RelayCommand(ConfirmSettings);
public Visibility NavigationVisibility { get; set; } = Visibility.Visible; public Visibility NavigationVisibility { get; set; } = Visibility.Visible;
public string ConfirmButtonText => App.IsFirstRun ? "Install" : "Save"; public string ConfirmButtonText => App.IsFirstRun ? Resources.Strings.Menu_Install : Resources.Strings.Menu_Save;
public bool ConfirmButtonEnabled { get; set; } = true; public bool ConfirmButtonEnabled { get; set; } = true;
public MainWindowViewModel(Window window) public MainWindowViewModel(Window window)
@ -42,7 +42,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
if (string.IsNullOrEmpty(App.BaseDirectory)) if (string.IsNullOrEmpty(App.BaseDirectory))
{ {
Controls.ShowMessageBox("You must set an install location", MessageBoxImage.Error); Controls.ShowMessageBox(Resources.Strings.Menu_InstallLocation_NotSet, MessageBoxImage.Error);
return; return;
} }
@ -60,7 +60,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
catch (UnauthorizedAccessException) catch (UnauthorizedAccessException)
{ {
Controls.ShowMessageBox( Controls.ShowMessageBox(
$"{App.ProjectName} does not have write access to the install location you've selected. Please choose another location.", Resources.Strings.Menu_InstallLocation_NoWritePerms,
MessageBoxImage.Error MessageBoxImage.Error
); );
return; return;
@ -76,11 +76,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
string suggestedChange = Path.Combine(App.BaseDirectory, App.ProjectName); string suggestedChange = Path.Combine(App.BaseDirectory, App.ProjectName);
MessageBoxResult result = Controls.ShowMessageBox( MessageBoxResult result = Controls.ShowMessageBox(
$"The folder you've chosen to install {App.ProjectName} to already exists and is NOT empty. It is strongly recommended for {App.ProjectName} to be installed to its own independent folder.\n\n" + string.Format(Resources.Strings.Menu_InstallLocation_NotEmpty, suggestedChange),
"Changing to the following location is suggested:\n" +
$"{suggestedChange}\n\n" +
"Would you like to change to the suggested location?\n" +
"Selecting 'No' will ignore this warning and continue installation.",
MessageBoxImage.Warning, MessageBoxImage.Warning,
MessageBoxButton.YesNoCancel, MessageBoxButton.YesNoCancel,
MessageBoxResult.Yes MessageBoxResult.Yes
@ -100,7 +96,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
) )
{ {
Controls.ShowMessageBox( Controls.ShowMessageBox(
$"{App.ProjectName} cannot be installed here. Please choose a different location, or resort to using the default location by clicking the reset button.", Resources.Strings.Menu_InstallLocation_CantInstall,
MessageBoxImage.Error, MessageBoxImage.Error,
MessageBoxButton.OK MessageBoxButton.OK
); );

View File

@ -26,7 +26,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
{ {
var dialog = new OpenFileDialog var dialog = new OpenFileDialog
{ {
Filter = "Font files|*.ttf;*.otf|All files|*.*" Filter = $"{Resources.Strings.Menu_FontFiles}|*.ttf;*.otf|{Resources.Strings.Menu_AllFiles}|*.*"
}; };
if (dialog.ShowDialog() != true) if (dialog.ShowDialog() != true)
@ -62,12 +62,12 @@ namespace Bloxstrap.UI.ViewModels.Menu
set => App.Settings.Prop.UseOldCharacterSounds = value; set => App.Settings.Prop.UseOldCharacterSounds = value;
} }
public IReadOnlyDictionary<string, Enums.CursorType> CursorTypes => CursorTypeEx.Selections; public IReadOnlyCollection<Enums.CursorType> CursorTypes => CursorTypeEx.Selections;
public string SelectedCursorType public Enums.CursorType SelectedCursorType
{ {
get => CursorTypes.FirstOrDefault(x => x.Value == App.Settings.Prop.CursorType).Key; get => App.Settings.Prop.CursorType;
set => App.Settings.Prop.CursorType = CursorTypes[value]; set => App.Settings.Prop.CursorType = value;
} }
public bool OldAvatarBackground public bool OldAvatarBackground
@ -82,12 +82,12 @@ namespace Bloxstrap.UI.ViewModels.Menu
set => App.Settings.Prop.UseDisableAppPatch = value; set => App.Settings.Prop.UseDisableAppPatch = value;
} }
public IReadOnlyDictionary<string, EmojiType> EmojiTypes => EmojiTypeEx.Selections; public IReadOnlyCollection<EmojiType> EmojiTypes => EmojiTypeEx.Selections;
public string SelectedEmojiType public EmojiType SelectedEmojiType
{ {
get => EmojiTypes.FirstOrDefault(x => x.Value == App.Settings.Prop.EmojiType).Key; get => App.Settings.Prop.EmojiType;
set => App.Settings.Prop.EmojiType = EmojiTypes[value]; set => App.Settings.Prop.EmojiType = value;
} }
public Visibility ChooseCustomFontVisibility => _usingCustomFont ? Visibility.Collapsed : Visibility.Visible; public Visibility ChooseCustomFontVisibility => _usingCustomFont ? Visibility.Collapsed : Visibility.Visible;
@ -100,5 +100,12 @@ namespace Bloxstrap.UI.ViewModels.Menu
get => App.Settings.Prop.DisableFullscreenOptimizations; get => App.Settings.Prop.DisableFullscreenOptimizations;
set => App.Settings.Prop.DisableFullscreenOptimizations = value; set => App.Settings.Prop.DisableFullscreenOptimizations = value;
} }
public string DisableFullscreenOptimisationsDescriptionText
{
get => string.Format(
Resources.Strings.Menu_Mods_Misc_DisableFullscreenOptimisations_Description,
"https://devblogs.microsoft.com/directx/demystifying-full-screen-optimizations/");
}
} }
} }

View File

@ -0,0 +1,14 @@
namespace Bloxstrap.UI.ViewModels.Menu
{
class PreInstallViewModel
{
public string Info2Text
{
get => string.Format(
Resources.Strings.Menu_PreInstall_Info_2,
"https://www.github.com/pizzaboxer/bloxstrap/wiki",
"https://www.github.com/pizzaboxer/bloxstrap/issues",
"https://discord.gg/nKjV3mGq6R");
}
}
}