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

View File

@ -213,7 +213,7 @@ namespace Bloxstrap
{
if (Process.GetProcessesByName(ProjectName).Length > 1 && !IsQuiet)
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
);
@ -232,7 +232,7 @@ namespace Bloxstrap
{
if (Settings.Prop.UseDisableAppPatch)
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
);

View File

@ -40,12 +40,14 @@
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
<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">
<!--<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>-->
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="securifybv.ShellLink" Version="0.1.0" />
<PackageReference Include="SharpZipLib" Version="1.4.2" />
<PackageReference Include="System.Resources.ResourceManager" Version="4.3.0" />
</ItemGroup>
<ItemGroup>
@ -61,4 +63,19 @@
</AssemblyAttribute>
</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>

View File

@ -137,7 +137,7 @@ namespace Bloxstrap
App.Logger.WriteLine(LOG_IDENT, "Performing connectivity check...");
SetStatus("Connecting to Roblox...");
SetStatus(Resources.Strings.Bootstrapper_Status_Connecting);
try
{
@ -148,12 +148,12 @@ namespace Bloxstrap
App.Logger.WriteLine(LOG_IDENT, "Connectivity check failed!");
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))
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))
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))
ex = ex.InnerException!;
@ -180,7 +180,7 @@ namespace Bloxstrap
{
Mutex.OpenExisting("Bloxstrap_SingletonMutex").Close();
App.Logger.WriteLine(LOG_IDENT, "Bloxstrap_SingletonMutex mutex exists, waiting...");
SetStatus("Waiting for other instances...");
SetStatus(Resources.Strings.Bootstrapper_Status_WaitingOtherInstances);
mutexExists = true;
}
catch (Exception)
@ -231,7 +231,7 @@ namespace Bloxstrap
await mutex.ReleaseAsync();
if (App.IsFirstRun && App.IsNoLaunch)
Dialog?.ShowSuccess($"{App.ProjectName} has successfully installed");
Dialog?.ShowSuccess(Resources.Strings.Bootstrapper_SuccessfullyInstalled);
else if (!App.IsNoLaunch && !_cancelFired)
await StartRoblox();
}
@ -263,8 +263,7 @@ namespace Bloxstrap
MessageBoxResult action = App.Settings.Prop.ChannelChangeMode switch
{
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" +
$"Would you like to switch to the default channel ({RobloxDeployment.DefaultChannel})?",
string.Format(Resources.Strings.Bootstrapper_ChannelOutOfDate, App.Settings.Prop.Channel, RobloxDeployment.DefaultChannel),
MessageBoxImage.Warning,
MessageBoxButton.YesNo
),
@ -291,7 +290,7 @@ namespace Bloxstrap
{
const string LOG_IDENT = "Bootstrapper::StartRoblox";
SetStatus("Starting {product}...");
SetStatus(Resources.Strings.Bootstrapper_Status_Starting);
if (_launchCommandLine == "--app" && App.Settings.Prop.UseDisableAppPatch)
{
@ -303,7 +302,7 @@ namespace Bloxstrap
if (!File.Exists(Path.Combine(Paths.System, "mfplat.dll")))
{
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
);
@ -635,7 +634,7 @@ namespace Bloxstrap
return;
}
SetStatus($"Getting the latest {App.ProjectName}...");
SetStatus(Resources.Strings.Bootstrapper_Status_UpgradingBloxstrap);
try
{
@ -676,7 +675,7 @@ namespace Bloxstrap
App.Logger.WriteException(LOG_IDENT, ex);
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
);
}
@ -692,7 +691,7 @@ namespace Bloxstrap
App.Logger.WriteLine(LOG_IDENT, $"Prompting to shut down all open Roblox instances");
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,
MessageBoxButton.OKCancel
);
@ -722,7 +721,7 @@ namespace Bloxstrap
App.Logger.WriteLine(LOG_IDENT, $"All Roblox processes closed");
}
SetStatus($"Uninstalling {App.ProjectName}...");
SetStatus(Resources.Strings.Bootstrapper_Status_Uninstalling);
App.ShouldSaveConfigs = false;
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
@ -852,7 +851,7 @@ namespace Bloxstrap
_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.Downloads);
@ -866,7 +865,7 @@ namespace Bloxstrap
if (Filesystem.GetFreeDiskSpace(Paths.Base) < totalSizeRequired)
{
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
);
@ -911,7 +910,7 @@ namespace Bloxstrap
if (Dialog is not null)
{
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
@ -1032,7 +1031,7 @@ namespace Bloxstrap
await ExtractPackage(package);
}
SetStatus("Installing WebView2, please wait...");
SetStatus(Resources.Strings.Bootstrapper_Status_InstallingWebView2);
ProcessStartInfo startInfo = new()
{
@ -1061,8 +1060,7 @@ namespace Bloxstrap
if (File.Exists(injectorLocation))
{
Controls.ShowMessageBox(
"Roblox has now finished rolling out the new game client update, featuring 64-bit support and the Hyperion anticheat. ReShade does not work with this update, and so it has now been disabled and removed from Bloxstrap.\n\n"+
"Your ReShade configuration files will still be saved, and you can locate them by opening the folder where Bloxstrap is installed to, and navigating to the Integrations folder. You can choose to delete these if you want.",
Resources.Strings.Bootstrapper_HyperionUpdateInfo,
MessageBoxImage.Warning
);
@ -1083,7 +1081,7 @@ namespace Bloxstrap
return;
}
SetStatus("Applying Roblox modifications...");
SetStatus(Resources.Strings.Bootstrapper_Status_ApplyingModifications);
// set executable flags for fullscreen optimizations
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
{
public static IReadOnlyDictionary<string, CursorType> Selections => new Dictionary<string, CursorType>
public static IReadOnlyCollection<CursorType> Selections => new CursorType[]
{
{ "Default", CursorType.Default },
{ "2013 (Angular)", CursorType.From2013 },
{ "2006 (Cartoony)", CursorType.From2006 },
CursorType.Default,
CursorType.From2013,
CursorType.From2006
};
}
}

View File

@ -2,13 +2,13 @@
{
static class EmojiTypeEx
{
public static IReadOnlyDictionary<string, EmojiType> Selections => new Dictionary<string, EmojiType>
public static IReadOnlyCollection<EmojiType> Selections => new EmojiType[]
{
{ "Default (Twemoji)", EmojiType.Default },
{ "Catmoji", EmojiType.Catmoji },
{ "Windows 11", EmojiType.Windows11 },
{ "Windows 10", EmojiType.Windows10 },
{ "Windows 8", EmojiType.Windows8 },
EmojiType.Default,
EmojiType.Catmoji,
EmojiType.Windows11,
EmojiType.Windows10,
EmojiType.Windows8
};
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.Graphics.Gdi;
@ -57,45 +58,45 @@ namespace Bloxstrap
};
// 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" },
{ "Vulkan", "Vulkan" },
{ "Direct3D 11", "D3D11" },
{ "Direct3D 10", "D3D10" },
{ "OpenGL", "OpenGL" }
{ RenderingMode.Default, "None" },
{ RenderingMode.Vulkan, "Vulkan" },
{ RenderingMode.D3D11, "D3D11" },
{ RenderingMode.D3D10, "D3D10" },
{ 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" },
{ "Voxel (Phase 1)", "Voxel" },
{ "ShadowMap (Phase 2)", "ShadowMap" },
{ "Future (Phase 3)", "Future" }
{ LightingMode.Default, "None" },
{ LightingMode.Voxel, "Voxel" },
{ LightingMode.ShadowMap, "ShadowMap" },
{ 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 },
{ "1x MSAA", "1" },
{ "2x MSAA", "2" },
{ "4x MSAA", "4" },
{ "8x MSAA", "8" }
{ MSAAMode.Default, null },
{ MSAAMode.x1, "1" },
{ MSAAMode.x2, "2" },
{ MSAAMode.x4, "4" },
{ 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" },
{ "Old (Pre-2022)", "NewTexturePack" },
{ "New (2022)", "OldTexturePack" }
{ MaterialVersion.Default, "None" },
{ MaterialVersion.Old, "NewTexturePack" },
{ MaterialVersion.New, "OldTexturePack" }
};
// 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?
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?>
{
{ "DisableV2", null },
@ -105,7 +106,7 @@ namespace Bloxstrap
},
{
"Version 1 (2015)",
InGameMenuVersion.V1,
new Dictionary<string, string?>
{
{ "DisableV2", "True" },
@ -115,7 +116,7 @@ namespace Bloxstrap
},
{
"Version 2 (2020)",
InGameMenuVersion.V2,
new Dictionary<string, string?>
{
{ "DisableV2", "False" },
@ -125,7 +126,7 @@ namespace Bloxstrap
},
{
"Version 4 (2023)",
InGameMenuVersion.V4,
new Dictionary<string, string?>
{
{ "DisableV2", "True" },
@ -195,7 +196,7 @@ namespace Bloxstrap
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)
{

View File

@ -33,7 +33,7 @@ namespace Bloxstrap
_installLocation = Path.GetDirectoryName(Paths.Process)!;
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,
MessageBoxButton.YesNo
);
@ -75,9 +75,7 @@ namespace Bloxstrap
App.Logger.WriteLine(LOG_IDENT, $"Drive has changed from {driveName} to {newDriveName}");
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" +
"\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.",
string.Format(Resources.Strings.InstallChecker_DriveLetterChangeDetected, driveName, newDriveName),
MessageBoxImage.Warning,
MessageBoxButton.OK
);
@ -90,7 +88,7 @@ namespace Bloxstrap
App.Logger.WriteLine(LOG_IDENT, $"Drive {driveName} does not exist anymore, and has likely been removed");
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,
MessageBoxButton.OKCancel
);
@ -168,7 +166,7 @@ namespace Bloxstrap
else
{
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,
MessageBoxButton.YesNo
);
@ -234,8 +232,8 @@ namespace Bloxstrap
if (isAutoUpgrade)
{
App.NotifyIcon?.ShowAlert(
$"{App.ProjectName} has been upgraded to v{currentVersionInfo.ProductVersion}",
"See what's new in this version",
string.Format(Resources.Strings.InstallChecker_Updated, currentVersionInfo.ProductVersion),
Resources.Strings.InstallChecker_SeeWhatsNew,
30,
(_, _) => Utilities.ShellExecute($"https://github.com/{App.ProjectRepository}/releases/tag/v{currentVersionInfo.ProductVersion}")
);
@ -243,7 +241,7 @@ namespace Bloxstrap
else if (!App.IsQuiet)
{
Controls.ShowMessageBox(
$"{App.ProjectName} has been upgraded to v{currentVersionInfo.ProductVersion}",
string.Format(Resources.Strings.InstallChecker_Updated, currentVersionInfo.ProductVersion),
MessageBoxImage.Information,
MessageBoxButton.OK
);

View File

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

View File

@ -91,8 +91,7 @@ namespace Bloxstrap
return;
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" +
$"Would you like to switch your preferred channel to {channel}?",
string.Format(Resources.Strings.ProtocolHandler_RobloxSwitchedChannel, channel, App.Settings.Prop.Channel),
MessageBoxImage.Question,
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:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:base="clr-namespace:Bloxstrap.UI.Elements.Base"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d"
Width="420"
MinHeight="0"
@ -44,7 +45,7 @@
<Border.Background>
<SolidColorBrush Color="{ui:ThemeResource SolidBackgroundFillColorSecondary}" Opacity="{Binding FooterOpacity, Mode=OneTime}" />
</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>
</Grid>
</base:WpfUiWindow>

View File

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

View File

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

View File

@ -6,9 +6,10 @@
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.ContextMenu"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels.ContextMenu"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
d:DataContext="{d:DesignInstance Type=models:LogTracerViewModel}"
mc:Ignorable="d"
Title="Log tracer"
Title="{x:Static resources:Strings.ContextMenu_LogTracer_Title}"
Width="800"
Height="480"
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
@ -22,13 +23,13 @@
<RowDefinition Height="Auto" />
</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}">
<ui:MenuItem Margin="4,8,0,8" Header="Keep on top" 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 Name="TextWrappingToggle" Margin="0,8,0,8" Header="Text wrapping" IsCheckable="True" IsChecked="False" />
<ui:MenuItem Margin="0,8,4,8" Header="Locate log file" Command="{Binding LocateLogFileCommand, Mode=OneTime}" />
<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="{x:Static resources:Strings.ContextMenu_LogTracer_ScrollToEnd}" IsCheckable="True" IsChecked="True" Click="AutoScrollMenuItem_Click" />
<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="{x:Static resources:Strings.Common_LocateLogFile}" Command="{Binding LocateLogFileCommand, Mode=OneTime}" />
</StackPanel>
<ScrollViewer x:Name="ScrollViewer" Grid.Row="2" VerticalAlignment="Top">
@ -51,7 +52,7 @@
<StatusBarItem>
<TextBlock>
<TextBlock.Text>
<MultiBinding Mode="OneWay" StringFormat="Tracing {0}">
<MultiBinding Mode="OneWay" StringFormat="{x:Static resources:Strings.ContextMenu_LogTracer_TracingFormat}">
<Binding Path="LogFilename" />
</MultiBinding>
</TextBlock.Text>

View File

@ -6,6 +6,7 @@
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.ContextMenu"
xmlns:base="clr-namespace:Bloxstrap.UI.Elements.Base"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d"
Title="ContextMenuContainer"
MinWidth="0"
@ -35,7 +36,7 @@
</MenuItem.Header>
</MenuItem>
<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.Header>
<Grid>
@ -44,7 +45,7 @@
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<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>
</MenuItem.Header>
</MenuItem>
@ -56,7 +57,7 @@
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<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>
</MenuItem.Header>
</MenuItem>
@ -68,11 +69,11 @@
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<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>
</MenuItem.Header>
</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>
</ui:UiWindow.ContextMenu>
</base:WpfUiWindow>

View File

@ -127,7 +127,7 @@ namespace Bloxstrap.UI.Elements.ContextMenu
private void CloseRobloxMenuItem_Click(object sender, RoutedEventArgs e)
{
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,
MessageBoxButton.YesNo
);

View File

@ -6,9 +6,10 @@
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.ContextMenu"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels.ContextMenu"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
d:DataContext="{d:DesignInstance Type=models:ServerInformationViewModel}"
mc:Ignorable="d"
Title="Server information"
Title="{x:Static resources:Strings.ContextMenu_ServerInformation_Title}"
MinWidth="0"
MinHeight="0"
Width="420"
@ -24,7 +25,7 @@
<RowDefinition Height="Auto" />
</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.RowDefinitions>
@ -38,23 +39,23 @@
<ColumnDefinition Width="*" />
</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="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="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="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}" />
</Grid>
<Border Grid.Row="2" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}">
<StackPanel Orientation="Horizontal" FlowDirection="LeftToRight" HorizontalAlignment="Right">
<Button MinWidth="100" Content="Copy Instance ID" Command="{Binding CopyInstanceIdCommand, Mode=OneTime}" />
<Button Margin="12,0,0,0" MinWidth="100" Content="Close" Command="{Binding CloseWindowCommand, 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="{x:Static resources:Strings.Common_Close}" Command="{Binding CloseWindowCommand, Mode=OneTime}" />
</StackPanel>
</Border>
</Grid>

View File

@ -5,8 +5,9 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Dialogs"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d"
Title="Add FastFlag"
Title="{x:Static resources:Strings.Dialog_AddFastFlag_Title}"
MinHeight="0"
Width="480"
SizeToContent="Height"
@ -21,7 +22,7 @@
<RowDefinition Height="Auto" />
</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.RowDefinitions>
@ -33,16 +34,16 @@
<ColumnDefinition Width="*" />
</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" />
<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" />
</Grid>
<Border Grid.Row="2" Margin="0,10,0,0" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}">
<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>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Style.Triggers>
@ -53,7 +54,7 @@
</Style>
</Button.Style>
</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>
</Border>
</Grid>

View File

@ -5,8 +5,9 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Dialogs"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d"
Title="Import JSON"
Title="{x:Static resources:Strings.Common_ImportJson}"
MinHeight="0"
Width="480"
SizeToContent="Height"
@ -21,11 +22,11 @@
<RowDefinition Height="Auto" />
</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">
<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>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Visibility" Value="Collapsed"/>
@ -36,13 +37,12 @@
</Style.Triggers>
</Style>
</TextBlock.Style>
Paste in your JSON here...
</TextBlock>
</Grid>
<Border Grid.Row="3" Margin="0,10,0,0" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}">
<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>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Style.Triggers>
@ -53,7 +53,7 @@
</Style>
</Button.Style>
</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>
</Border>
</Grid>

View File

@ -5,6 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Dialogs"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d"
Width="480"
MinHeight="0"
@ -19,7 +20,7 @@
<RowDefinition Height="Auto" />
</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.ColumnDefinitions>
@ -30,14 +31,14 @@
<StackPanel Grid.Column="1">
<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 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" />
</StackPanel>
</Grid>
<Border Grid.Row="2" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}">
<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>
</Border>
</Grid>

View File

@ -18,7 +18,7 @@ namespace Bloxstrap.UI.Elements.Dialogs
{
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;
AddException(exception);

View File

@ -5,7 +5,9 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Dialogs"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d"
Title="{x:Static resources:Strings.Dialog_Exception_Title}"
Width="540"
MinHeight="0"
SizeToContent="Height"
@ -19,7 +21,7 @@
<RowDefinition Height="Auto" />
</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.ColumnDefinitions>
@ -28,21 +30,21 @@
</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" />
<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" />
<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>
</Grid>
<Border Grid.Row="2" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}">
<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">
<ComboBoxItem Content="Submit report..." Visibility="Collapsed" />
<ComboBoxItem Content="Submit report via GitHub" />
<ComboBoxItem Content="Submit report via Discord" />
<ComboBoxItem Content="{x:Static resources:Strings.Dialog_Exception_SubmitReport}" Visibility="Collapsed" />
<ComboBoxItem Content="{x:Static resources:Strings.Dialog_Exception_SubmitReportGithub}" Tag="github" />
<ComboBoxItem Content="{x:Static resources:Strings.Dialog_Exception_SubmitReportDiscord}" Tag="discord" />
</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>
</Border>
</Grid>

View File

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

View File

@ -7,8 +7,9 @@
xmlns:pages="clr-namespace:Bloxstrap.UI.Elements.Menu.Pages"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:base="clr-namespace:Bloxstrap.UI.Elements.Base"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d"
Title="Bloxstrap Menu"
Title="{x:Static resources:Strings.Menu_Title}"
MinWidth="960"
Width="960"
Height="580"
@ -23,7 +24,7 @@
<RowDefinition Height="Auto" />
</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.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.Items>
<ui:NavigationItem Content="Integrations" 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="FastFlags" 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="Behaviour" 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="About" PageType="{x:Type pages:AboutPage}" Icon="QuestionCircle48" Tag="about" />
<ui:NavigationItem Content="{x:Static resources:Strings.Menu_Integrations_Title}" PageType="{x:Type pages:IntegrationsPage}" Icon="Add28" Tag="integrations" />
<ui:NavigationItem Content="{x:Static resources:Strings.Menu_Mods_Title}" PageType="{x:Type pages:ModsPage}" Icon="WrenchScrewdriver20" Tag="mods" />
<ui:NavigationItem Content="{x:Static resources:Strings.Menu_FastFlags_Title}" PageType="{x:Type pages:FastFlagsPage}" Icon="Flag24" Tag="fastflags" />
<ui:NavigationItem Content="{x:Static resources:Strings.Menu_Appearance_Title}" PageType="{x:Type pages:AppearancePage}" Icon="PaintBrush24" Tag="appearance" />
<ui:NavigationItem Content="{x:Static resources:Strings.Menu_Behaviour_Title}" PageType="{x:Type pages:BehaviourPage}" Icon="Settings24" Tag="behaviour" />
<ui:NavigationItem Content="{x:Static resources:Strings.Menu_Installation_Title}" PageType="{x:Type pages:InstallationPage}" Icon="HardDrive20" Tag="installation" />
<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="Before you install..." PageType="{x:Type pages:PreInstallPage}" Tag="preinstall" Visibility="Collapsed" />
<ui:NavigationItem Content="{x:Static resources:Strings.Menu_FastFlagEditor_Title}" PageType="{x:Type pages:FastFlagEditorPage}" Tag="fastflageditor" 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>

View File

@ -22,6 +22,10 @@ namespace Bloxstrap.UI.Elements.Menu
App.Logger.WriteLine("MainWindow::MainWindow", "Initializing menu");
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");

View File

@ -5,6 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d"
d:DesignHeight="700" d:DesignWidth="800"
Title="AboutPage"
@ -30,20 +31,20 @@
<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}" />
</Grid>
<TextBlock Text="An open-source, feature-packed alternative bootstrapper for Roblox" 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_1}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock Text="{x:Static resources:Strings.Menu_About_Description_2}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</Grid>
<StackPanel Orientation="Horizontal">
<ui:Anchor Margin="0,16,4,0" Content="GitHub repository" 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="Help and Information" 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="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="{x:Static resources:Strings.Menu_About_ReportIssue}" Icon="Chat48" NavigateUri="https://github.com/pizzaboxer/bloxstrap/issues" />
<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="{x:Static resources:Strings.Menu_About_DiscordServer}" Icon="Chat48" NavigateUri="https://discord.gg/nKjV3mGq6R" />
</StackPanel>
<StackPanel Visibility="{Binding BuildInformationVisibility, Mode=OneTime}">
<TextBlock Text="Build Information" 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_BuildInformation}" FontWeight="Medium" FontSize="20" Margin="0,16,0,0" />
<TextBlock Text="{x:Static resources:Strings.Menu_About_UnreleasedVersion}" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<Grid Column="0" Margin="0,8,0,0">
<Grid.RowDefinitions>
@ -76,8 +77,8 @@
</Grid>
</StackPanel>
<TextBlock Text="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}" FontWeight="Medium" FontSize="20" Margin="0,16,0,0" />
<TextBlock Text="{x:Static resources:Strings.Menu_About_Contributors_Description}" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<Grid Column="0" Margin="0,8,0,0">
<Grid.RowDefinitions>
<!-- bruh -->
@ -185,7 +186,7 @@
</Grid>
<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.RowDefinitions>
<RowDefinition Height="*" />

View File

@ -4,36 +4,49 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d"
d:DesignHeight="520" d:DesignWidth="800"
Title="AppearancePage"
Scrollable="True">
<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.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Theme" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Dark theme does not apply to Legacy or Vista styles." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Appearance_Theme_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Appearance_Theme_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</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 Margin="0,8,0,0">
<ui:CardControl.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Style" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose how the bootstrapper should look." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Appearance_Style_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Appearance_Style_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</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 Margin="0,8,0,0">
<ui:CardControl.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Icon" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose what icon the bootstrapper should use." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Appearance_Icon_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Appearance_Icon_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<Grid Width="200">
@ -46,7 +59,13 @@
<ImageBrush ImageSource="{Binding IconPreviewSource, Mode=OneWay}" />
</Border.Background>
</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>
</ui:CardControl>
<ui:CardExpander Margin="0,8,0,0" IsExpanded="False">
@ -57,8 +76,8 @@
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock FontSize="14" Text="Bootstrapper customization" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Configure other customizable Bootstrapper options." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Appearance_Customisation_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Appearance_Customisation_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</Grid>
</ui:CardExpander.Header>
@ -73,22 +92,22 @@
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
</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}" />
<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.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<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>
<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>
</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>
</ui:UiPage>

View File

@ -6,6 +6,7 @@
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Menu.Pages"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels.Menu"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
d:DataContext="{d:DesignInstance Type=models:BehaviourViewModel}"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="800"
@ -13,13 +14,13 @@
Scrollable="True">
<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.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Create desktop icon" />
<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 FontSize="14" Text="{x:Static resources:Strings.Menu_Behaviour_CreateDesktopIcon_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Behaviour_CreateDesktopIcon_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding CreateDesktopIcon, Mode=TwoWay}" />
@ -28,8 +29,8 @@
<ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Automatically update Bloxstrap" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Bloxstrap will automatically check and update itself when launching Roblox." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Behaviour_AutoUpdate_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Behaviour_AutoUpdate_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding UpdateCheckingEnabled, Mode=TwoWay}" />
@ -43,8 +44,8 @@
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock FontSize="14" Text="Channel" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose which deployment channel Roblox should be downloaded from." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Behaviour_Channel_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Behaviour_Channel_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</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}" />
</Grid>
@ -75,13 +76,13 @@
<ColumnDefinition Width="*" />
</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="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="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}" />
<StackPanel Grid.Row="3" Grid.ColumnSpan="2" Margin="0,16,0,0" Orientation="Horizontal">
@ -96,7 +97,7 @@
</Style>
</StackPanel.Style>
<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>
</Grid>
@ -151,11 +152,17 @@
<ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Automatic channel change action" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Roblox or Bloxstrap may try to change your preferred channel." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Behaviour_AutoChannelChange_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Behaviour_AutoChannelChange_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</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 Margin="0,8,0,0">
@ -170,8 +177,8 @@
</ui:CardControl.Style>
<ui:CardControl.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Force Roblox reinstallation" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Roblox will be installed fresh on next launch." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Behaviour_ForceRobloxReinstall_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Behaviour_ForceRobloxReinstall_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding ForceRobloxReinstallation, Mode=TwoWay}" />

View File

@ -5,6 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Menu.Pages"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="FastFlagEditorPage"
@ -17,12 +18,12 @@
<RowDefinition Height="*" />
</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">
<ui:Button Icon="ArrowLeft48" Content="Back" Click="BackButton_Click" />
<ui:Button Icon="Add28" Content="Add new" 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="ArrowLeft48" Content="{x:Static resources:Strings.Menu_FastFlagEditor_Back}" Click="BackButton_Click" />
<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="{x:Static resources:Strings.Menu_FastFlagEditor_DeleteSelected}" Click="DeleteButton_Click" Appearance="Danger" Margin="12,0,0,0">
<ui:Button.Style>
<Style TargetType="ui:Button" BasedOn="{StaticResource {x:Type ui:Button}}">
<Style.Triggers>
@ -33,11 +34,11 @@
</Style>
</ui:Button.Style>
</ui:Button>
<ToggleButton x:Name="TogglePresetsButton" Content="Show preset flags" Click="ToggleButton_Click" Margin="12,0,0,0" />
<ui:Button Icon="ArrowImport24" Content="Import JSON" Margin="12,0,0,0" Click="ImportJSONButton_Click" />
<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="{x:Static resources:Strings.Common_ImportJson}" Margin="12,0,0,0" Click="ImportJSONButton_Click" />
</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.Style>
@ -87,8 +88,8 @@
</DataGrid.CellStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" />
<DataGridTextColumn Header="Value" Binding="{Binding Value}" Width="*" />
<DataGridTextColumn Header="{x:Static resources:Strings.Common_Name}" Binding="{Binding Name}" />
<DataGridTextColumn Header="{x:Static resources:Strings.Common_Value}" Binding="{Binding Value}" Width="*" />
</DataGrid.Columns>
</DataGrid>
</Grid>

View File

@ -5,13 +5,15 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
xmlns:controls="clr-namespace:Bloxstrap.ControlsWpf"
mc:Ignorable="d"
d:DesignHeight="1000" d:DesignWidth="800"
Title="FastFlagsPage"
Scrollable="True"
Loaded="Page_Loaded">
<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.ColumnDefinitions>
@ -21,26 +23,26 @@
<ui:CardAction Grid.Column="0" Margin="0,0,4,0" Icon="EditSettings24" Command="{Binding OpenFastFlagEditorCommand}">
<StackPanel>
<TextBlock FontSize="14" Text="FastFlag Editor" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Manage your own FastFlags." Padding="0,0,16,0" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlagEditor_Title}" />
<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>
</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">
<StackPanel>
<TextBlock FontSize="14" Text="Help" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Learn more about FastFlags." Padding="0,0,16,0" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Common_Help}" />
<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>
</ui:CardAction>
</Grid>
<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.Header>
<StackPanel>
<TextBlock FontSize="14" Text="HTTP request logging" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Enables logging of HTTP requests (DFLogHttpTraceLight=12)." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_Debug_HttpRequestLogging_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_Debug_HttpRequestLogging_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding HttpRequestLogging, Mode=TwoWay}" />
@ -48,8 +50,8 @@
<ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header>
<StackPanel>
<TextBlock FontSize="14" Text="HTTP proxy address" />
<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 FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_Debug_HttpProxyAddress_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_Debug_HttpProxyAddress_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<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.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Flag state overlay" />
<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 FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_Debug_FlagStateOverlay_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_Debug_FlagStateOverlay_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<ui:TextBox Margin="5,0,0,0" Padding="10,5,10,5" Width="200" Text="{Binding StateOverlayFlags, Mode=TwoWay}" />
</ui:CardControl>
</StackPanel>
<TextBlock Text="Presets" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
<TextBlock Foreground="{DynamicResource TextFillColorSecondaryBrush}">
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>
<TextBlock Text="{x:Static resources:Strings.Common_Presets}" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
<controls:MarkdownTextBlock MarkdownText="{Binding Direct3DExclusiveFullscreenInfoText}"/>
<ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header>
<StackPanel>
@ -79,14 +77,14 @@
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</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">
<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" />
</Hyperlink>
</TextBlock>
</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>
</ui:CardControl.Header>
<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.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Preferred lighting technology" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose which lighting technology should be forced enabled in all games." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_LightingTechnology_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_LightingTechnology_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</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 Margin="0,8,0,0">
<ui:CardControl.Header>
@ -108,17 +112,23 @@
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</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">
<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" />
</Hyperlink>
</TextBlock>
</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>
</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 Margin="0,8,0,0">
<ui:CardControl.Header>
@ -128,16 +138,14 @@
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</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">
<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" />
</Hyperlink>
</TextBlock>
</Grid>
<TextBlock Margin="0,2,0,0" FontSize="12" Foreground="{DynamicResource TextFillColorTertiaryBrush}">
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>
<controls:MarkdownTextBlock Margin="0,2,0,0" FontSize="12" Foreground="{DynamicResource TextFillColorTertiaryBrush}" MarkdownText="{Binding HideGuisDescriptionText}"/>
</StackPanel>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding GuiHidingEnabled, Mode=TwoWay}" />
@ -150,26 +158,38 @@
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</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">
<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" />
</Hyperlink>
</TextBlock>
</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>
</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 Margin="0,8,0,0">
<ui:CardControl.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Rendering mode" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose what renderer Roblox should use. VR requires Direct3D/Automatic." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_RenderingMode_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_RenderingMode_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</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 Margin="0,8,0,0">
<ui:CardControl.Header>
@ -179,14 +199,14 @@
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</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">
<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" />
</Hyperlink>
</TextBlock>
</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>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding FixDisplayScaling, Mode=TwoWay}" />
@ -194,8 +214,8 @@
<ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Use alternate graphics quality selector" />
<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 FontSize="14" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_AltGraphicsSelector_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_FastFlags_Presets_AltGraphicsSelector_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding AlternateGraphicsSelectorEnabled, Mode=TwoWay}" />

View File

@ -7,13 +7,14 @@
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Menu.Pages"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels"
xmlns:viewmodels="clr-namespace:Bloxstrap.UI.ViewModels.Menu"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
d:DataContext="{d:DesignInstance Type=viewmodels:InstallationViewModel}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="InstallationPage">
<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.Style>
@ -28,8 +29,8 @@
</ui:CardExpander.Style>
<ui:CardExpander.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Install Location" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose where Bloxstrap should be installed to." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Installation_InstallLocation_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Installation_InstallLocation_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardExpander.Header>
<Grid>
@ -39,8 +40,8 @@
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<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="2" Margin="4,0,0,0" Height="35" Icon="ArrowCounterclockwise24" Content="Reset" Command="{Binding ResetInstallLocationCommand}" />
<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="{x:Static resources:Strings.Common_Reset}" Command="{Binding ResetInstallLocationCommand}" />
</Grid>
</ui:CardExpander>
@ -63,15 +64,15 @@
<ui:CardAction Grid.Column="0" x:Name="OpenFolderCardAction" Margin="0,0,4,0" Icon="Folder24" Command="{Binding OpenFolderCommand}" >
<StackPanel>
<TextBlock FontSize="14" Text="Open Installation Folder" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Where Bloxstrap is currently installed to." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Installation_OpenInstallFolder_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Installation_OpenInstallFolder_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</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">
<StackPanel>
<TextBlock FontSize="14" Text="Looking to uninstall?" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Here's a guide on how to uninstall Bloxstrap." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Installation_UninstallGuide_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Installation_UninstallGuide_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardAction>
</Grid>

View File

@ -6,14 +6,15 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
mc:Ignorable="d"
d:DesignHeight="1080" d:DesignWidth="800"
Title="IntegrationsPage"
Scrollable="True">
<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.Header>
<StackPanel>
@ -22,14 +23,14 @@
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</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">
<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" />
</Hyperlink>
</TextBlock>
</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>
</ui:CardControl.Header>
<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.Header>
<StackPanel>
<TextBlock FontSize="14" Text="See server location when joining a game" />
<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 FontSize="14" Text="{x:Static resources:Strings.Menu_Integrations_ShowServerDetails_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Integrations_ShowServerDetails_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding ShowServerDetailsEnabled, Mode=TwoWay}" />
</ui:CardControl>
<TextBlock Text="Discord Rich Presence" 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 Text="{x:Static resources:Strings.Common_DiscordRichPresence}" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
<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.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Show game activity" />
<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 FontSize="14" Text="{x:Static resources:Strings.Menu_Integrations_ShowGameActivity_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Integrations_ShowGameActivity_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<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.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Allow activity joining" />
<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 FontSize="14" Text="{x:Static resources:Strings.Menu_Integrations_AllowActivityJoining_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Integrations_AllowActivityJoining_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding DiscordActivityJoinEnabled, Mode=TwoWay}" />
</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.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Allow multi-instance launching" />
<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 FontSize="14" Text="{x:Static resources:Strings.Menu_Integrations_AllowMultipleInstances_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Integrations_AllowMultipleInstances_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding MultiInstanceLaunchingEnabled, Mode=TwoWay}" />
</ui:CardControl>
<TextBlock Text="Custom Integrations" 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 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="{x:Static resources:Strings.Menu_Integrations_Custom_Description}" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<Grid Margin="0,8,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
@ -93,8 +94,8 @@
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</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="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="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="{x:Static resources:Strings.Common_Delete}" HorizontalAlignment="Stretch" Appearance="Danger" IsEnabled="{Binding IsCustomIntegrationSelected, Mode=OneWay}" Command="{Binding DeleteIntegrationCommand, Mode=OneTime}" />
</Grid>
<StackPanel Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Margin="4,0,0,0">
<StackPanel.Style>
@ -106,15 +107,15 @@
</Style.Triggers>
</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}" />
<TextBlock Margin="0,8,0,0" Text="Application Location" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<ui:TextBox Margin="0,4,0,0" PlaceholderText="e.g. C:\Windows\System32\cmd.exe" Text="{Binding SelectedCustomIntegration.Location}" />
<TextBlock Margin="0,8,0,0" Text="Launch Args" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<ui:TextBox Margin="0,4,0,0" PlaceholderText="e.g. /k echo Roblox is running!" Text="{Binding SelectedCustomIntegration.LaunchArgs}" />
<CheckBox Margin="0,8,0,0" Content="Auto close when Roblox closes" IsChecked="{Binding SelectedCustomIntegration.AutoClose}" />
<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="{x:Static resources:Strings.Menu_Integrations_Custom_AppLocation_Placeholder}" Text="{Binding SelectedCustomIntegration.Location}" />
<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="{x:Static resources:Strings.Menu_Integrations_Custom_LaunchArgs_Placeholder}" Text="{Binding SelectedCustomIntegration.LaunchArgs}" />
<CheckBox Margin="0,8,0,0" Content="{x:Static resources:Strings.Menu_Integrations_Custom_AutoClose}" IsChecked="{Binding SelectedCustomIntegration.AutoClose}" />
</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>
<Style>
<Style.Triggers>

View File

@ -5,12 +5,14 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
xmlns:controls="clr-namespace:Bloxstrap.ControlsWpf"
mc:Ignorable="d"
d:DesignHeight="800" d:DesignWidth="800"
Title="ModsPage"
Scrollable="True">
<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.RowDefinitions>
@ -23,7 +25,7 @@
</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}">
<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-->
<TextBlock.Style>
<Style>
@ -39,11 +41,11 @@
<TextBlock Margin="0,2,0,0" FontSize="12" Foreground="{DynamicResource TextFillColorTertiaryBrush}">
<TextBlock.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>
<DataTrigger Binding="{Binding ElementName=OpenModFolderCardAction, Path=IsEnabled, Mode=OneTime}" Value="False">
<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>
</Style.Triggers>
</Style>
@ -53,19 +55,19 @@
</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">
<StackPanel>
<TextBlock FontSize="14" Text="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 FontSize="14" Text="{x:Static resources:Strings.Common_Help}" />
<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>
</ui:CardAction>
</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.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Use old death sound" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Bring back the classic 'oof' death sound." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_Presets_OldDeathSound_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Mods_Presets_OldDeathSound_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding OldDeathSoundEnabled, Mode=TwoWay}" />
@ -74,18 +76,24 @@
<ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Mouse cursor" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose between using two classic Roblox cursor styles." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_Presets_MouseCursor_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Mods_Presets_MouseCursor_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</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 Margin="0,8,0,0">
<ui:CardControl.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Use old avatar editor background" />
<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 FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_Presets_OldAvatarEditor_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Mods_Presets_OldAvatarEditor_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding OldAvatarBackground, Mode=TwoWay}" />
@ -94,8 +102,8 @@
<ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Emulate old character sounds" />
<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 FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_Presets_OldCharacterSounds_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Mods_Presets_OldCharacterSounds_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding OldCharacterSoundsEnabled, Mode=TwoWay}" />
@ -104,8 +112,8 @@
<ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Disable desktop app" />
<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 FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_Presets_DisableDesktopApp_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Mods_Presets_DisableDesktopApp_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding DisableAppPatchEnabled, Mode=TwoWay}" />
@ -114,35 +122,37 @@
<ui:CardControl Margin="0,8,0,0">
<ui:CardControl.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Preferred emoji type" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="Choose which type of emoji should Roblox use." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_Presets_EmojiType_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Text="{x:Static resources:Strings.Menu_Mods_Presets_EmojiType_Description}" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel>
</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>
<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.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Apply custom font" />
<TextBlock Margin="0,2,0,0" FontSize="12" Foreground="{DynamicResource TextFillColorTertiaryBrush}">
Forces every in-game font to be a font that you choose.
</TextBlock>
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_Misc_CustomFont_Title}" />
<TextBlock Margin="0,2,0,0" FontSize="12" Foreground="{DynamicResource TextFillColorTertiaryBrush}" Text="{x:Static resources:Strings.Menu_Mods_Misc_CustomFont_Description}" />
</StackPanel>
</ui:CardControl.Header>
<StackPanel>
<ui:Button Icon="DocumentAdd16" Content="Choose font..." 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="DocumentAdd16" Content="{x:Static resources:Strings.Menu_Mods_Misc_CustomFont_Choose}" Command="{Binding ManageCustomFontCommand}" Visibility="{Binding ChooseCustomFontVisibility, 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>
</ui:CardControl>
<ui:CardControl x:Name="FullscreenOptimizationsToggle" Margin="0,8,0,0">
<ui:CardControl.Header>
<StackPanel>
<TextBlock FontSize="14" Text="Disable fullscreen optimizations" />
<TextBlock Margin="0,2,0,0" FontSize="12" Foreground="{DynamicResource TextFillColorTertiaryBrush}">
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>
<TextBlock FontSize="14" Text="{x:Static resources:Strings.Menu_Mods_Misc_DisableFullscreenOptimisations_Title}" />
<controls:MarkdownTextBlock Margin="0,2,0,0" FontSize="12" Foreground="{DynamicResource TextFillColorTertiaryBrush}" MarkdownText="{Binding DisableFullscreenOptimisationsDescriptionText, Mode=OneTime}"/>
</StackPanel>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding DisableFullscreenOptimizations, Mode=TwoWay}" />

View File

@ -6,6 +6,8 @@
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Menu.Pages"
xmlns:models="clr-namespace:Bloxstrap.UI.ViewModels"
xmlns:resources="clr-namespace:Bloxstrap.Resources"
xmlns:controls="clr-namespace:Bloxstrap.ControlsWpf"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="PreInstallPage"
@ -22,22 +24,15 @@
<ColumnDefinition Width="*" />
</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}">
<Image RenderOptions.BitmapScalingMode="HighQuality" Source="pack://application:,,,/Resources/Menu/StartMenu.png" />
</Border>
<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 Margin="0,16,0,0" FontSize="14" TextWrapping="Wrap">
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>
<TextBlock FontSize="14" TextWrapping="Wrap" Text="{x:Static resources:Strings.Menu_PreInstall_Info_1}" />
<controls:MarkdownTextBlock Margin="0,16,0,0" FontSize="14" TextWrapping="Wrap" MarkdownText="{Binding Info2Text, Mode=OneTime}" />
</StackPanel>
</Grid>
</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>
/// Interaction logic for PreInstallPage.xaml
@ -7,6 +9,7 @@
{
public PreInstallPage()
{
DataContext = new PreInstallViewModel();
InitializeComponent();
}
}

View File

@ -11,9 +11,11 @@ namespace Bloxstrap.UI.ViewModels.ContextMenu
private readonly ActivityWatcher _activityWatcher;
public string InstanceId => _activityWatcher.ActivityJobId;
public string ServerType => $"{_activityWatcher.ActivityServerType} server";
public string ServerLocation { get; private set; } = "Loading, please wait...";
public string UdmuxProxied => _activityWatcher.ActivityMachineUDMUX ? "Yes" : "No";
public string ServerType => string.Format(
Resources.Strings.ContextMenu_ServerInformation_TypeFormat,
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 CloseWindowCommand => new RelayCommand(_window.Close);

View File

@ -4,7 +4,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
{
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;

View File

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

View File

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

View File

@ -7,6 +7,7 @@ using Wpf.Ui.Mvvm.Contracts;
using CommunityToolkit.Mvvm.Input;
using Bloxstrap.UI.Elements.Menu.Pages;
using Bloxstrap.Enums.FlagPresets;
namespace Bloxstrap.UI.ViewModels.Menu
{
@ -58,9 +59,9 @@ namespace Bloxstrap.UI.ViewModels.Menu
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");
set
@ -82,15 +83,15 @@ namespace Bloxstrap.UI.ViewModels.Menu
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
{
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 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);
}
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
{
@ -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");
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";
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()
{
Name = "New Integration"
Name = Resources.Strings.Menu_Integrations_Custom_NewIntegration
});
SelectedCustomIntegrationIndex = CustomIntegrations.Count - 1;

View File

@ -19,7 +19,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
public ICommand ConfirmSettingsCommand => new RelayCommand(ConfirmSettings);
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 MainWindowViewModel(Window window)
@ -42,7 +42,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
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;
}
@ -60,7 +60,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
catch (UnauthorizedAccessException)
{
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
);
return;
@ -76,11 +76,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
string suggestedChange = Path.Combine(App.BaseDirectory, App.ProjectName);
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" +
"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.",
string.Format(Resources.Strings.Menu_InstallLocation_NotEmpty, suggestedChange),
MessageBoxImage.Warning,
MessageBoxButton.YesNoCancel,
MessageBoxResult.Yes
@ -100,7 +96,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
)
{
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,
MessageBoxButton.OK
);

View File

@ -26,7 +26,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
{
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)
@ -62,12 +62,12 @@ namespace Bloxstrap.UI.ViewModels.Menu
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;
set => App.Settings.Prop.CursorType = CursorTypes[value];
get => App.Settings.Prop.CursorType;
set => App.Settings.Prop.CursorType = value;
}
public bool OldAvatarBackground
@ -82,12 +82,12 @@ namespace Bloxstrap.UI.ViewModels.Menu
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;
set => App.Settings.Prop.EmojiType = EmojiTypes[value];
get => App.Settings.Prop.EmojiType;
set => App.Settings.Prop.EmojiType = value;
}
public Visibility ChooseCustomFontVisibility => _usingCustomFont ? Visibility.Collapsed : Visibility.Visible;
@ -100,5 +100,12 @@ namespace Bloxstrap.UI.ViewModels.Menu
get => App.Settings.Prop.DisableFullscreenOptimizations;
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");
}
}
}