初始化 monorepo: Go后端(7微服务) + Unity客户端(9模块) + 启动器 HTML5原型: Three.js 3D体素世界, Perlin噪声地形, 原版材质, 22种方块 Minecraft创造模式背包: 双栏布局, 拖拽移动物品, 方向性元件引脚 AI助搭策划文档 + 客户端/服务端骨架 + Docker Compose + CI
This commit is contained in:
@@ -0,0 +1,957 @@
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using PCL.Core.App;
|
||||
using PCL.Core.App.Configuration;
|
||||
using PCL.Core.UI;
|
||||
using PCL.Core.Utils;
|
||||
using PCL.Core.App.Localization;
|
||||
|
||||
namespace PCL;
|
||||
|
||||
public partial class PageSetupUI
|
||||
{
|
||||
public string[] ThemeColors => Basics.IsAprilFool
|
||||
? [Lang.Text("Setup.Ui.Theme.Color.SkyBlue"), Lang.Text("Setup.Ui.Theme.Color.CatBlue"), Lang.Text("Setup.Ui.Theme.Color.CrashBlue"), Lang.Text("Setup.Ui.Theme.Color.Hmcl")]
|
||||
: [Lang.Text("Setup.Ui.Theme.Color.SkyBlue"), Lang.Text("Setup.Ui.Theme.Color.CatBlue"), Lang.Text("Setup.Ui.Theme.Color.CrashBlue")];
|
||||
|
||||
public new bool isLoaded;
|
||||
|
||||
public PageSetupUI()
|
||||
{
|
||||
InitializeComponent();
|
||||
Loaded += PageSetupUI_Loaded;
|
||||
Loaded += (_, _) => HiddenRefresh();
|
||||
}
|
||||
|
||||
private void PageSetupUI_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// 重复加载部分
|
||||
PanBack.ScrollToHome();
|
||||
|
||||
ModAnimation.AniControlEnabled += 1;
|
||||
Reload(); // #4826,在每次进入页面时都刷新一下
|
||||
ModAnimation.AniControlEnabled -= 1;
|
||||
|
||||
// 非重复加载部分
|
||||
if (isLoaded)
|
||||
return;
|
||||
isLoaded = true;
|
||||
|
||||
SliderLoad();
|
||||
|
||||
PanLauncherHide.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
public void Reload()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 启动器
|
||||
SliderLauncherOpacity.Value = Config.Preference.Theme.WindowOpacity;
|
||||
CheckLauncherLogo.Checked = Config.Preference.ShowStartupLogo;
|
||||
ComboDarkMode.SelectedIndex = (int)Config.Preference.Theme.ColorMode;
|
||||
ComboDarkColor.SelectedIndex = (int)Config.Preference.Theme.DarkColor;
|
||||
ComboLightColor.SelectedIndex = (int)Config.Preference.Theme.LightColor;
|
||||
CheckShowLaunchingHint.Checked = Config.Preference.ShowLaunchingHint;
|
||||
|
||||
// 字体设置
|
||||
ComboUiFont.SelectedFontTag = Config.Preference.Font;
|
||||
ComboUiMotdFont.SelectedFontTag = Config.Preference.MotdFont;
|
||||
|
||||
CheckBlur.Checked = Config.Preference.Blur.IsEnabled;
|
||||
SliderBlurValue.Value = Config.Preference.Blur.Radius;
|
||||
SliderBlurSamplingRate.Value = Config.Preference.Blur.SamplingRate;
|
||||
ComboBlurType.SelectedIndex = Config.Preference.Blur.KernelType;
|
||||
PanBlurValue.Visibility = CheckBlur.Checked == true ? Visibility.Visible : Visibility.Collapsed;
|
||||
CheckLockWindowSize.Checked = Config.Preference.LockWindowSize;
|
||||
|
||||
// 背景图片
|
||||
SliderBackgroundOpacity.Value = Config.Preference.Background.WallpaperOpacity;
|
||||
SliderBackgroundBlur.Value = Config.Preference.Background.WallpaperBlurRadius;
|
||||
ComboBackgroundSuit.SelectedIndex = Config.Preference.Background.WallpaperSuitMode;
|
||||
CheckBackgroundColorful.Checked = Config.Preference.Background.BackgroundColorful;
|
||||
var autoPauseVideo = Config.Preference.Background.AutoPauseVideo;
|
||||
CheckAutoPauseVideo.Checked = autoPauseVideo;
|
||||
if (ModVideoBack.IsGaming)
|
||||
if (autoPauseVideo)
|
||||
BtnBackgroundRefresh.IsEnabled = false;
|
||||
|
||||
BackgroundRefresh(false, false);
|
||||
|
||||
// 标题栏
|
||||
((MyRadioBox)FindName("RadioLogoType" + (int)Config.Preference.WindowTitleType))
|
||||
.Checked = true;
|
||||
CheckLogoLeft.Visibility = RadioLogoType0.Checked ? Visibility.Visible : Visibility.Collapsed;
|
||||
PanLogoText.Visibility = RadioLogoType2.Checked ? Visibility.Visible : Visibility.Collapsed;
|
||||
PanLogoChange.Visibility = RadioLogoType3.Checked ? Visibility.Visible : Visibility.Collapsed;
|
||||
TextLogoText.Text = Config.Preference.WindowTitleCustomText;
|
||||
CheckLogoLeft.Checked = Config.Preference.TopBarLeftAlign;
|
||||
|
||||
// 背景音乐
|
||||
CheckMusicRandom.Checked = Config.Preference.Music.ShufflePlayback;
|
||||
CheckMusicAuto.Checked = Config.Preference.Music.StartOnStartup;
|
||||
CheckMusicStop.Checked = Config.Preference.Music.StopInGame;
|
||||
CheckMusicStart.Checked = Config.Preference.Music.StartInGame;
|
||||
CheckMusicSMTC.Checked = Config.Preference.Music.EnableSMTC;
|
||||
SliderMusicVolume.Value = Config.Preference.Music.Volume;
|
||||
MusicRefreshUI();
|
||||
|
||||
// 主页
|
||||
try
|
||||
{
|
||||
ComboCustomPreset.SelectedIndex = Config.Preference.Homepage.SelectedPreset;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Config.Preference.Homepage.SelectedPresetConfig.Reset();
|
||||
}
|
||||
|
||||
((MyRadioBox)FindName("RadioCustomType" + Config.Preference.Homepage.Type)).Checked = true;
|
||||
TextCustomNet.Text = Config.Preference.Homepage.CustomUrl;
|
||||
ModSetup.UiCustomType(Config.Preference.Homepage.Type);
|
||||
|
||||
// 功能隐藏
|
||||
// 获取配置组引用
|
||||
var uiHidden = Config.Preference.Hide;
|
||||
|
||||
// 主页面
|
||||
CheckHiddenPageDownload.Checked = uiHidden.PageDownload;
|
||||
CheckHiddenPageSetup.Checked = uiHidden.PageSetup;
|
||||
CheckHiddenPageTools.Checked = uiHidden.PageTools;
|
||||
|
||||
// 子页面 设置
|
||||
CheckHiddenSetupLaunch.Checked = uiHidden.SetupLaunch;
|
||||
CheckHiddenSetupUI.Checked = uiHidden.SetupUi;
|
||||
CheckHiddenSetupLauncherLanguage.Checked = uiHidden.SetupLauncherLanguage;
|
||||
CheckHiddenSetupGameManage.Checked = uiHidden.SetupGameManage;
|
||||
CheckHiddenSetupJava.Checked = uiHidden.SetupJava;
|
||||
CheckHiddenLauncherMisc.Checked = uiHidden.SetupLauncherMisc;
|
||||
CheckHiddenSetupUpdate.Checked = uiHidden.SetupUpdate;
|
||||
CheckHiddenSetupGameLink.Checked = uiHidden.SetupGameLink;
|
||||
CheckHiddenSetupAbout.Checked = uiHidden.SetupAbout;
|
||||
CheckHiddenSetupFeedback.Checked = uiHidden.SetupFeedback;
|
||||
CheckHiddenSetupLog.Checked = uiHidden.SetupLog;
|
||||
|
||||
// 子页面 工具
|
||||
CheckHiddenToolsGameLink.Checked = uiHidden.ToolsGameLink;
|
||||
CheckHiddenToolsTest.Checked = uiHidden.ToolsTest;
|
||||
|
||||
// 子页面 实例设置
|
||||
CheckHiddenVersionEdit.Checked = uiHidden.InstanceEdit;
|
||||
CheckHiddenVersionExport.Checked = uiHidden.InstanceExport;
|
||||
CheckHiddenVersionSave.Checked = uiHidden.InstanceSave;
|
||||
CheckHiddenVersionScreenshot.Checked = uiHidden.InstanceScreenshot;
|
||||
CheckHiddenVersionMod.Checked = uiHidden.InstanceMod;
|
||||
CheckHiddenVersionResourcePack.Checked = uiHidden.InstanceResourcePack;
|
||||
CheckHiddenVersionShader.Checked = uiHidden.InstanceShader;
|
||||
CheckHiddenVersionSchematic.Checked = uiHidden.InstanceSchematic;
|
||||
CheckHiddenVersionServer.Checked = uiHidden.InstanceServer;
|
||||
|
||||
// 特定功能
|
||||
CheckHiddenFunctionSelect.Checked = uiHidden.FunctionSelect;
|
||||
CheckHiddenFunctionModUpdate.Checked = uiHidden.FunctionModUpdate;
|
||||
CheckHiddenFunctionHidden.Checked = uiHidden.FunctionHidden;
|
||||
}
|
||||
catch (NullReferenceException ex)
|
||||
{
|
||||
ModBase.Log(
|
||||
ex,
|
||||
Lang.Text("Setup.Ui.Error.ConfigReset"),
|
||||
ModBase.LogLevel.Msgbox,
|
||||
userSummary: Lang.Text("Setup.Ui.Error.ConfigReset"));
|
||||
Reset();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ModBase.Log(
|
||||
ex,
|
||||
Lang.Text("Setup.Ui.Error.LoadFailed"),
|
||||
ModBase.LogLevel.Feedback,
|
||||
userSummary: Lang.Text("Setup.Ui.Error.LoadFailed"));
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
public void Reset()
|
||||
{
|
||||
try
|
||||
{
|
||||
Config.Preference.Reset();
|
||||
ModBase.Log("[Setup] 已初始化个性化设置!");
|
||||
HintService.Hint(Lang.Text("Setup.Ui.Initialized"), HintType.Success, false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ModBase.Log(
|
||||
ex,
|
||||
Lang.Text("Setup.Ui.Error.InitFailed"),
|
||||
ModBase.LogLevel.Msgbox,
|
||||
userSummary: Lang.Text("Setup.Ui.Error.InitFailed"));
|
||||
}
|
||||
|
||||
Reload();
|
||||
}
|
||||
|
||||
// 将控件改变路由到设置改变
|
||||
private void SliderChange(object senderRaw, bool user)
|
||||
{
|
||||
var sender = (MySlider)senderRaw;
|
||||
if (ModAnimation.AniControlEnabled == 0)
|
||||
SetByTag(sender.Tag?.ToString(), sender.Value);
|
||||
}
|
||||
|
||||
private void ComboChange(object senderRaw, SelectionChangedEventArgs e)
|
||||
{
|
||||
var sender = (MyComboBox)senderRaw;
|
||||
if (ModAnimation.AniControlEnabled == 0)
|
||||
SetByTag(sender.Tag?.ToString(), sender.SelectedIndex);
|
||||
}
|
||||
|
||||
private void CheckBoxChange(object senderRaw, bool user)
|
||||
{
|
||||
var sender = (MyCheckBox)senderRaw;
|
||||
if (ModAnimation.AniControlEnabled == 0)
|
||||
SetByTag(sender.Tag?.ToString(), sender.Checked);
|
||||
}
|
||||
|
||||
private void TextBoxChange(object senderRaw, RoutedEventArgs e)
|
||||
{
|
||||
var sender = (MyTextBox)senderRaw;
|
||||
if (ModAnimation.AniControlEnabled == 0)
|
||||
SetByTag(sender.Tag?.ToString(), sender.Text);
|
||||
}
|
||||
|
||||
private void RadioBoxChange(object senderRaw, ModBase.RouteEventArgs e)
|
||||
{
|
||||
var sender = (MyRadioBox)senderRaw;
|
||||
var gotCfg = sender.Tag?.ToString()?.Split("/") ?? Array.Empty<string>();
|
||||
if (ModAnimation.AniControlEnabled == 0 && gotCfg.Length >= 2)
|
||||
SetByTag(gotCfg[0], int.Parse(gotCfg[1]));
|
||||
}
|
||||
|
||||
private static void SetByTag(string tag, object value)
|
||||
{
|
||||
ConfigService.TrySetValue(tag, value);
|
||||
}
|
||||
|
||||
private void ComboFontChange(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (ModAnimation.AniControlEnabled == 0) Config.Preference.Font = ComboUiFont.SelectedFontTag;
|
||||
}
|
||||
|
||||
private void ComboMotdFontChange(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (ModAnimation.AniControlEnabled == 0) Config.Preference.MotdFont = ComboUiMotdFont.SelectedFontTag;
|
||||
}
|
||||
|
||||
// 背景图片
|
||||
private void BtnUIBgOpen_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
ModBase.OpenExplorer(ModBase.exePath + @"PCL\Pictures\");
|
||||
}
|
||||
|
||||
private void BtnBackgroundRefresh_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
BackgroundRefresh(true, true);
|
||||
}
|
||||
|
||||
public void BackgroundRefreshUI(bool show, int count)
|
||||
{
|
||||
if (PanBackgroundOpacity is null)
|
||||
return;
|
||||
if (show)
|
||||
{
|
||||
PanBackgroundOpacity.Visibility = Visibility.Visible;
|
||||
PanBackgroundBlur.Visibility = Visibility.Visible;
|
||||
PanBackgroundSuit.Visibility = Visibility.Visible;
|
||||
BtnBackgroundClear.Visibility = Visibility.Visible;
|
||||
CheckAutoPauseVideo.Visibility = Visibility.Visible;
|
||||
CardBackground.Title = Lang.Text("Setup.Ui.Background.TitleWithCount", count);
|
||||
}
|
||||
else
|
||||
{
|
||||
PanBackgroundOpacity.Visibility = Visibility.Collapsed;
|
||||
PanBackgroundBlur.Visibility = Visibility.Collapsed;
|
||||
PanBackgroundSuit.Visibility = Visibility.Collapsed;
|
||||
BtnBackgroundClear.Visibility = Visibility.Collapsed;
|
||||
CheckAutoPauseVideo.Visibility = Visibility.Collapsed;
|
||||
CardBackground.Title = Lang.Text("Setup.Ui.Background.TitleDefault");
|
||||
}
|
||||
|
||||
CardBackground.TriggerForceResize();
|
||||
}
|
||||
|
||||
private void BtnBackgroundClear_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (ModMain.MyMsgBox(Lang.Text("Setup.Ui.Background.Clear.Confirm.Message"),
|
||||
Lang.Text("Common.Dialog.Warning"), button2: Lang.Text("Common.Action.Cancel"),
|
||||
isWarn: true) == 1)
|
||||
{
|
||||
ModBase.DeleteDirectory(ModBase.exePath + @"PCL\Pictures");
|
||||
BackgroundRefresh(false, true);
|
||||
HintService.Hint(Lang.Text("Setup.Ui.Background.Clear.Success"), HintType.Success);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新背景图片及设置页 UI。
|
||||
/// </summary>
|
||||
/// <param name="isHint">是否显示刷新提示。</param>
|
||||
/// <param name="refresh">是否刷新图片显示。</param>
|
||||
public static void BackgroundRefresh(bool isHint, bool refresh)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 获取可用的图片文件
|
||||
Directory.CreateDirectory(ModBase.exePath + @"PCL\Pictures\");
|
||||
var pic = ModBase.EnumerateFiles(ModBase.exePath + @"PCL\Pictures\").Where(file =>
|
||||
!(file.Extension.Equals(".ini", StringComparison.OrdinalIgnoreCase) ||
|
||||
file.Extension.Equals(".db", StringComparison.OrdinalIgnoreCase))).Select(file => file.FullName)
|
||||
.ToList();
|
||||
|
||||
// 视频加载异常处理
|
||||
|
||||
EventHandler<ExceptionRoutedEventArgs> videoHandler = (sender, e) =>
|
||||
{
|
||||
var videoEx = e.ErrorException;
|
||||
var videoAddress = ModMain.frmMain.VideoBack.Source.ToString();
|
||||
if (ModMain.frmMain.VideoBack.Source is not null)
|
||||
{
|
||||
ModVideoBack.VideoStop();
|
||||
|
||||
if (videoEx.Message.Contains("0xC00D109B"))
|
||||
ModBase.Log(
|
||||
$"""
|
||||
刷新背景内容失败,该视频文件可能并非 H.264(AVC)格式。
|
||||
你可以尝试使用视频转码工具打开视频文件并设定目标格式为 H.264(AVC),然后转码该视频。
|
||||
文件:{videoAddress}
|
||||
""",
|
||||
ModBase.LogLevel.Msgbox,
|
||||
userSummary: Lang.Text("Setup.Ui.Error.BackgroundVideoUnsupported"));
|
||||
else
|
||||
ModBase.Log(
|
||||
videoEx,
|
||||
$"刷新背景内容失败({videoAddress})",
|
||||
ModBase.LogLevel.Msgbox,
|
||||
userSummary: Lang.Text("Setup.Ui.Error.OperationFailed"));
|
||||
}
|
||||
};
|
||||
ModMain.frmMain.VideoBack.MediaFailed -= videoHandler;
|
||||
ModVideoBack.GamingStateChanged -= ModVideoBack.OnGamingStateChanged;
|
||||
ModVideoBack.ForcePlayChanged -= ModVideoBack.OnForcePlayChanged;
|
||||
ModVideoBack.GamingStateChanged += ModVideoBack.OnGamingStateChanged;
|
||||
ModVideoBack.ForcePlayChanged += ModVideoBack.OnForcePlayChanged;
|
||||
if (!Config.Preference.Background.AutoPauseVideo)
|
||||
ModVideoBack.ForcePlay = true;
|
||||
// 加载
|
||||
if (pic.Count == 0)
|
||||
{
|
||||
if (refresh)
|
||||
{
|
||||
if (ModMain.frmMain.ImgBack.Visibility == Visibility.Collapsed)
|
||||
{
|
||||
if (isHint)
|
||||
HintService.Hint(Lang.Text("Setup.Ui.Background.NoAvailableContent"), HintType.Error);
|
||||
}
|
||||
else
|
||||
{
|
||||
ModMain.frmMain.ImgBack.Visibility = Visibility.Collapsed;
|
||||
if (isHint)
|
||||
HintService.Hint(Lang.Text("Setup.Ui.Background.Cleared"), HintType.Success);
|
||||
}
|
||||
}
|
||||
|
||||
if (ModMain.frmSetupUI is not null)
|
||||
ModMain.frmSetupUI.BackgroundRefreshUI(false, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (refresh)
|
||||
{
|
||||
var address = RandomUtils.PickRandom(pic);
|
||||
try
|
||||
{
|
||||
ModMain.frmMain.ImgBack.Background = null;
|
||||
ModVideoBack.VideoStop();
|
||||
ModBase.Log("[UI] 加载背景内容:" + address);
|
||||
ModMain.frmMain.ImgBack.Background = new MyBitmap(address);
|
||||
_ = Config.Preference.Background.WallpaperSuitMode;
|
||||
ModMain.frmMain.ImgBack.Visibility = Visibility.Visible;
|
||||
if (isHint)
|
||||
HintService.Hint(Lang.Text("Setup.Ui.Background.Refresh.Success", ModBase.GetFileNameFromPath(address)), HintType.Success,
|
||||
false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
ModMain.frmMain.VideoBack.MediaFailed += videoHandler;
|
||||
ModBase.Log(ex, "[UI] 加载背景图片失败" + address);
|
||||
if (ModBase.modeDebug)
|
||||
HintService.Hint(Lang.Text("Setup.Ui.Background.ImageLoadFailed", address));
|
||||
ModMain.frmMain.ImgBack.Visibility = Visibility.Visible;
|
||||
ModMain.frmMain.VideoBack.Source = new Uri(address, UriKind.Absolute);
|
||||
ModVideoBack.VideoPlay();
|
||||
if (isHint)
|
||||
HintService.Hint(Lang.Text("Setup.Ui.Background.Refresh.Success", ModBase.GetFileNameFromPath(address)), HintType.Success,
|
||||
false);
|
||||
}
|
||||
catch (Exception playEx)
|
||||
{
|
||||
ModBase.Log(playEx, "播放背景内容时出现未知错误:");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ModMain.frmSetupUI is not null)
|
||||
ModMain.frmSetupUI.BackgroundRefreshUI(true, pic.Count);
|
||||
}
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
ModBase.Log(
|
||||
ex,
|
||||
"刷新背景内容时出现未知错误",
|
||||
ModBase.LogLevel.Feedback,
|
||||
userSummary: Lang.Text("Setup.Ui.Error.OperationFailed"));
|
||||
}
|
||||
}
|
||||
|
||||
// 顶部栏
|
||||
private void BtnLogoChange_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
var fileName = SystemDialogs.SelectFile(
|
||||
Lang.Text("Setup.Ui.ImageFile.Filter"),
|
||||
Lang.Text("Setup.Ui.ImageFile.SelectTitle"));
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
return;
|
||||
try
|
||||
{
|
||||
// 拷贝文件
|
||||
File.Delete(ModBase.exePath + @"PCL\Logo.png");
|
||||
ModBase.CopyFile(fileName, ModBase.exePath + @"PCL\Logo.png");
|
||||
// 设置当前显示
|
||||
ModMain.frmMain.ImageTitleLogo.Source = null; // 防止因为 Source 属性前后的值相同而不更新 (#5628)
|
||||
ModMain.frmMain.ImageTitleLogo.Source = ModBase.exePath + @"PCL\Logo.png";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex.Message.Contains("参数无效"))
|
||||
ModBase.Log(
|
||||
"""
|
||||
改变标题栏图片失败,该图片文件可能并非标准格式。
|
||||
你可以尝试使用画图打开该文件并重新保存,这会让图片变为标准格式。
|
||||
""",
|
||||
ModBase.LogLevel.Msgbox,
|
||||
userSummary: Lang.Text("Setup.Ui.Error.TitleImageInvalidFormat"));
|
||||
else
|
||||
ModBase.Log(
|
||||
ex,
|
||||
"设置标题栏图片失败",
|
||||
ModBase.LogLevel.Msgbox,
|
||||
userSummary: Lang.Text("Setup.Ui.Error.OperationFailed"));
|
||||
ModMain.frmMain.ImageTitleLogo.Source = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void RadioLogoType3_Check(object sender, ModBase.RouteEventArgs e)
|
||||
{
|
||||
if (!(ModAnimation.AniControlEnabled == 0 && e.raiseByMouse))
|
||||
return;
|
||||
Refresh: ;
|
||||
|
||||
// 已有图片则不再选择
|
||||
if (File.Exists(ModBase.exePath + @"PCL\Logo.png"))
|
||||
{
|
||||
try
|
||||
{
|
||||
ModMain.frmMain.ImageTitleLogo.Source = null; // 防止因为 Source 属性前后的值相同而不更新 (#5628)
|
||||
ModMain.frmMain.ImageTitleLogo.Source = ModBase.exePath + @"PCL\Logo.png";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex.Message.Contains("参数无效"))
|
||||
ModBase.Log(
|
||||
"""
|
||||
调整标题栏图片失败,该图片文件可能并非标准格式。
|
||||
你可以尝试使用画图打开该文件并重新保存,这会让图片变为标准格式。
|
||||
""",
|
||||
ModBase.LogLevel.Msgbox,
|
||||
userSummary: Lang.Text("Setup.Ui.Error.TitleImageResizeInvalidFormat"));
|
||||
else
|
||||
ModBase.Log(
|
||||
ex,
|
||||
"调整标题栏图片失败",
|
||||
ModBase.LogLevel.Msgbox,
|
||||
userSummary: Lang.Text("Setup.Ui.Error.OperationFailed"));
|
||||
ModMain.frmMain.ImageTitleLogo.Source = null;
|
||||
e.handled = true;
|
||||
try
|
||||
{
|
||||
File.Delete(ModBase.exePath + @"PCL\Logo.png");
|
||||
}
|
||||
catch (Exception exx)
|
||||
{
|
||||
ModBase.Log(
|
||||
exx,
|
||||
"清理错误的标题栏图片失败",
|
||||
ModBase.LogLevel.Msgbox,
|
||||
userSummary: Lang.Text("Setup.Ui.Error.OperationFailed"));
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 没有图片则要求选择
|
||||
var fileName = SystemDialogs.SelectFile(Lang.Text("Setup.Ui.ImageFile.Filter"), Lang.Text("Setup.Ui.ImageFile.SelectTitle"));
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
{
|
||||
ModMain.frmMain.ImageTitleLogo.Source = null;
|
||||
e.handled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
// 拷贝文件
|
||||
File.Delete(ModBase.exePath + @"PCL\Logo.png");
|
||||
ModBase.CopyFile(fileName, ModBase.exePath + @"PCL\Logo.png");
|
||||
goto Refresh;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ModBase.Log(
|
||||
ex,
|
||||
"复制标题栏图片失败",
|
||||
ModBase.LogLevel.Msgbox,
|
||||
userSummary: Lang.Text("Setup.Ui.Error.OperationFailed"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void BtnLogoDelete_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(ModBase.exePath + @"PCL\Logo.png");
|
||||
RadioLogoType1.SetChecked(true, true);
|
||||
HintService.Hint(Lang.Text("Setup.Ui.Logo.Clear.Success"), HintType.Success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ModBase.Log(
|
||||
ex,
|
||||
"清空标题栏图片失败",
|
||||
ModBase.LogLevel.Msgbox,
|
||||
userSummary: Lang.Text("Setup.Ui.Error.OperationFailed"));
|
||||
}
|
||||
}
|
||||
|
||||
// 背景音乐
|
||||
private void BtnMusicOpen_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
ModBase.OpenExplorer(ModBase.exePath + @"PCL\Musics\");
|
||||
}
|
||||
|
||||
private void BtnMusicRefresh_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
ModMusic.MusicRefreshPlay(true);
|
||||
}
|
||||
|
||||
public void MusicRefreshUI()
|
||||
{
|
||||
if (PanBackgroundOpacity is null)
|
||||
return;
|
||||
if (ModMusic.musicAllList.Any())
|
||||
{
|
||||
PanMusicVolume.Visibility = Visibility.Visible;
|
||||
PanMusicDetail.Visibility = Visibility.Visible;
|
||||
BtnMusicClear.Visibility = Visibility.Visible;
|
||||
CardMusic.Title = Lang.Text("Setup.Ui.Music.TitleWithCount", ModBase.EnumerateFiles(ModBase.exePath + @"PCL\Musics\").Count());
|
||||
}
|
||||
else
|
||||
{
|
||||
PanMusicVolume.Visibility = Visibility.Collapsed;
|
||||
PanMusicDetail.Visibility = Visibility.Collapsed;
|
||||
BtnMusicClear.Visibility = Visibility.Collapsed;
|
||||
CardMusic.Title = Lang.Text("Setup.Ui.Music.Title");
|
||||
}
|
||||
|
||||
CardMusic.TriggerForceResize();
|
||||
}
|
||||
|
||||
private void BtnMusicClear_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (ModMain.MyMsgBox(Lang.Text("Setup.Ui.Music.Clear.Confirm.Message"),
|
||||
Lang.Text("Common.Dialog.Warning"), button2: Lang.Text("Common.Action.Cancel"),
|
||||
isWarn: true) == 1)
|
||||
ModBase.RunInThread(() =>
|
||||
{
|
||||
HintService.Hint(Lang.Text("Setup.Ui.Music.Deleting"));
|
||||
// 停止播放音乐
|
||||
ModMusic.musicNAudio = null;
|
||||
ModMusic.musicWaitingList = new List<string>();
|
||||
ModMusic.musicAllList = new List<string>();
|
||||
Thread.Sleep(200);
|
||||
// 删除文件
|
||||
try
|
||||
{
|
||||
ModBase.DeleteDirectory(ModBase.exePath + @"PCL\Musics");
|
||||
// DisableSMTCSupport()
|
||||
HintService.Hint(Lang.Text("Setup.Ui.Music.Delete.Success"), HintType.Success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ModBase.Log(
|
||||
ex,
|
||||
"删除背景音乐失败",
|
||||
ModBase.LogLevel.Msgbox,
|
||||
userSummary: Lang.Text("Setup.Ui.Error.OperationFailed"));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(ModBase.exePath + @"PCL\Musics");
|
||||
ModBase.RunInUi(() => ModMusic.MusicRefreshPlay(false));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ModBase.Log(
|
||||
ex,
|
||||
"重建背景音乐文件夹失败",
|
||||
ModBase.LogLevel.Msgbox,
|
||||
userSummary: Lang.Text("Setup.Ui.Error.OperationFailed"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void CheckMusicStart_Change(object sender, bool user)
|
||||
{
|
||||
CheckBoxChange(sender, user);
|
||||
if (ModAnimation.AniControlEnabled != 0)
|
||||
return;
|
||||
if (CheckMusicStart.Checked == true)
|
||||
CheckMusicStop.Checked = false;
|
||||
}
|
||||
|
||||
private void CheckMusicStop_Change()
|
||||
{
|
||||
if (ModAnimation.AniControlEnabled != 0)
|
||||
return;
|
||||
if (CheckMusicStop.Checked == true)
|
||||
CheckMusicStart.Checked = false;
|
||||
}
|
||||
|
||||
// 主页
|
||||
|
||||
private void BtnCustomRefresh_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
ModMain.frmLaunchRight.ForceRefresh();
|
||||
HintService.Hint(Lang.Text("Setup.Ui.Homepage.Refresh.Success"), HintType.Success);
|
||||
}
|
||||
|
||||
private void BtnCustomTutorial_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
ModBase.OpenWebsite("https://docs.pclc.cc/ce/customization/xaml-format");
|
||||
}
|
||||
|
||||
// 主题
|
||||
private void ThemeColor_Change(object senderRaw, SelectionChangedEventArgs e)
|
||||
{
|
||||
var sender = (MyComboBox)senderRaw;
|
||||
SetByTag(sender.Tag?.ToString(), sender.SelectedIndex);
|
||||
ThemeManager.ThemeRefresh();
|
||||
}
|
||||
|
||||
// 赞助
|
||||
private void BtnLauncherDonate_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
ModBase.OpenWebsite("https://afdian.com/a/LTCat");
|
||||
}
|
||||
|
||||
// 滑动条
|
||||
private void SliderLoad()
|
||||
{
|
||||
SliderMusicVolume.getHintText = new Func<object, object>(v =>
|
||||
Lang.Number(Math.Ceiling(Convert.ToDouble(v) * 0.1d) / 100d, "P0"));
|
||||
SliderLauncherOpacity.getHintText = new Func<object, object>(v =>
|
||||
Lang.Number(Math.Round(40 + Convert.ToDouble(v) * 0.1d) / 100d, "P0"));
|
||||
SliderBackgroundOpacity.getHintText = new Func<object, object>(v =>
|
||||
Lang.Number(Math.Round(Convert.ToDouble(v) * 0.1d) / 100d, "P0"));
|
||||
SliderBackgroundBlur.getHintText = new Func<object, object>(v => Lang.Text("Setup.Ui.Slider.Pixel", Lang.Number(Convert.ToDouble(v), "N0")));
|
||||
SliderBlurValue.getHintText = new Func<object, object>(v => Lang.Text("Setup.Ui.Slider.Pixel", Lang.Number(Convert.ToDouble(v), "N0")));
|
||||
SliderBlurSamplingRate.getHintText = new Func<object, object>(v => Lang.Number(Convert.ToDouble(v) / 100d, "P0"));
|
||||
}
|
||||
|
||||
private void CheckMusicStart_OnChange(object sender, bool user)
|
||||
{
|
||||
CheckBoxChange(sender, user);
|
||||
CheckMusicStart_Change(sender, user);
|
||||
}
|
||||
|
||||
private void CheckMusicStop_OnChange(object sender, bool user)
|
||||
{
|
||||
CheckBoxChange(sender, user);
|
||||
CheckMusicStop_Change();
|
||||
}
|
||||
|
||||
#region 功能隐藏
|
||||
|
||||
/// <summary>
|
||||
/// 是否强制显示被禁用的功能。
|
||||
/// </summary>
|
||||
public static bool HiddenForceShow
|
||||
{
|
||||
get => field;
|
||||
set
|
||||
{
|
||||
field = value;
|
||||
HiddenRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新功能隐藏带来的显示变化。
|
||||
/// </summary>
|
||||
public static void HiddenRefresh()
|
||||
{
|
||||
if (ModMain.frmMain.PanTitleSelect is null || !ModMain.frmMain.PanTitleSelect.IsLoaded)
|
||||
return;
|
||||
try
|
||||
{
|
||||
// 获取配置组引用以缩短代码
|
||||
var conf = Config.Preference.Hide;
|
||||
|
||||
// 顶部栏:下载、设置、工具
|
||||
var isAllTitleHidden = !HiddenForceShow && conf.PageDownload && conf.PageSetup && conf.PageTools;
|
||||
|
||||
if (isAllTitleHidden)
|
||||
{
|
||||
ModMain.frmMain.PanTitleSelect.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
else
|
||||
{
|
||||
ModMain.frmMain.PanTitleSelect.Visibility = Visibility.Visible;
|
||||
ModMain.frmMain.BtnTitleSelect1.Visibility = !HiddenForceShow && conf.PageDownload
|
||||
? Visibility.Collapsed
|
||||
: Visibility.Visible;
|
||||
ModMain.frmMain.BtnTitleSelect2.Visibility =
|
||||
!HiddenForceShow && conf.PageSetup ? Visibility.Collapsed : Visibility.Visible;
|
||||
ModMain.frmMain.BtnTitleSelect3.Visibility =
|
||||
!HiddenForceShow && conf.PageTools ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
|
||||
// 功能隐藏设置卡片
|
||||
if (ModMain.frmSetupUI is not null)
|
||||
{
|
||||
ModMain.frmSetupUI.CardSwitch.Visibility = !HiddenForceShow && conf.FunctionHidden
|
||||
? Visibility.Collapsed
|
||||
: Visibility.Visible;
|
||||
ModMain.frmSetupUI.CardSwitch.Title = HiddenForceShow ? Lang.Text("Setup.Ui.FeatureHide.TitleTemporarilyDisabled") : Lang.Text("Setup.Ui.FeatureHide.Title");
|
||||
}
|
||||
|
||||
// 设置子页面 (FrmSetupLeft)
|
||||
if (ModMain.frmSetupLeft is not null)
|
||||
{
|
||||
ModMain.frmSetupLeft.ItemLaunch.Visibility =
|
||||
!HiddenForceShow && conf.SetupLaunch ? Visibility.Collapsed : Visibility.Visible;
|
||||
ModMain.frmSetupLeft.ItemUI.Visibility =
|
||||
!HiddenForceShow && conf.SetupUi ? Visibility.Collapsed : Visibility.Visible;
|
||||
ModMain.frmSetupLeft.ItemLauncherLanguage.Visibility = !HiddenForceShow && conf.SetupLauncherLanguage
|
||||
? Visibility.Collapsed
|
||||
: Visibility.Visible;
|
||||
ModMain.frmSetupLeft.ItemGameManage.Visibility = !HiddenForceShow && conf.SetupGameManage
|
||||
? Visibility.Collapsed
|
||||
: Visibility.Visible;
|
||||
ModMain.frmSetupLeft.ItemLauncherMisc.Visibility = !HiddenForceShow && conf.SetupLauncherMisc
|
||||
? Visibility.Collapsed
|
||||
: Visibility.Visible;
|
||||
ModMain.frmSetupLeft.ItemJava.Visibility =
|
||||
!HiddenForceShow && conf.SetupJava ? Visibility.Collapsed : Visibility.Visible;
|
||||
ModMain.frmSetupLeft.ItemUpdate.Visibility =
|
||||
!HiddenForceShow && conf.SetupUpdate ? Visibility.Collapsed : Visibility.Visible;
|
||||
ModMain.frmSetupLeft.ItemGameLink.Visibility = !HiddenForceShow && conf.SetupGameLink
|
||||
? Visibility.Collapsed
|
||||
: Visibility.Visible;
|
||||
ModMain.frmSetupLeft.ItemAbout.Visibility =
|
||||
!HiddenForceShow && conf.SetupAbout ? Visibility.Collapsed : Visibility.Visible;
|
||||
ModMain.frmSetupLeft.ItemFeedback.Visibility = !HiddenForceShow && conf.SetupFeedback
|
||||
? Visibility.Collapsed
|
||||
: Visibility.Visible;
|
||||
ModMain.frmSetupLeft.ItemLog.Visibility =
|
||||
!HiddenForceShow && conf.SetupLog ? Visibility.Collapsed : Visibility.Visible;
|
||||
|
||||
var categories = new[]
|
||||
{
|
||||
(ModMain.frmSetupLeft.TextGameCategory,
|
||||
!(conf.SetupLaunch && conf.SetupJava && conf.SetupGameManage)),
|
||||
(ModMain.frmSetupLeft.TextToolsCategory, !conf.SetupGameLink),
|
||||
(ModMain.frmSetupLeft.TextLauncherCategory, !(conf.SetupUi && conf.SetupLauncherLanguage && conf.SetupLauncherMisc)),
|
||||
(ModMain.frmSetupLeft.TextAboutCategory,
|
||||
!(conf.SetupAbout && conf.SetupUpdate && conf.SetupFeedback && conf.SetupLog))
|
||||
};
|
||||
|
||||
foreach (var category in categories)
|
||||
{
|
||||
var isVisible = category.Item2 || HiddenForceShow;
|
||||
category.Item1.Visibility = isVisible ? Visibility.Visible : Visibility.Collapsed;
|
||||
if (isVisible)
|
||||
category.Item1.Opacity = 0.6d;
|
||||
}
|
||||
|
||||
// 统计设置页可用项数量
|
||||
var setupCount = 0;
|
||||
if (!conf.SetupLaunch)
|
||||
setupCount += 1;
|
||||
if (!conf.SetupUi)
|
||||
setupCount += 1;
|
||||
if (!conf.SetupLauncherLanguage)
|
||||
setupCount += 1;
|
||||
if (!conf.SetupGameManage)
|
||||
setupCount += 1;
|
||||
if (!conf.SetupLauncherMisc)
|
||||
setupCount += 1;
|
||||
if (!conf.SetupJava)
|
||||
setupCount += 1;
|
||||
if (!conf.SetupUpdate)
|
||||
setupCount += 1;
|
||||
if (!conf.SetupGameLink)
|
||||
setupCount += 1;
|
||||
if (!conf.SetupAbout)
|
||||
setupCount += 1;
|
||||
if (!conf.SetupFeedback)
|
||||
setupCount += 1;
|
||||
if (!conf.SetupLog)
|
||||
setupCount += 1;
|
||||
ModMain.frmSetupLeft.PanItem.Visibility =
|
||||
setupCount < 2 && !HiddenForceShow ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
|
||||
// 工具子页面 (FrmToolsLeft)
|
||||
if (ModMain.frmToolsLeft is not null)
|
||||
{
|
||||
ModMain.frmToolsLeft.ItemGameLink.Visibility = !HiddenForceShow && conf.ToolsGameLink
|
||||
? Visibility.Collapsed
|
||||
: Visibility.Visible;
|
||||
ModMain.frmToolsLeft.ItemTest.Visibility =
|
||||
!HiddenForceShow && conf.ToolsTest ? Visibility.Collapsed : Visibility.Visible;
|
||||
|
||||
// 处理分类标题
|
||||
var isGameLinkVisible = (!HiddenForceShow && !conf.ToolsGameLink) || HiddenForceShow;
|
||||
ModMain.frmToolsLeft.TextGameLinkCategory.Visibility = isGameLinkVisible ? Visibility.Visible : Visibility.Collapsed;
|
||||
if (isGameLinkVisible) ModMain.frmToolsLeft.TextGameLinkCategory.Opacity = 0.6;
|
||||
|
||||
var isToolsVisible = (!HiddenForceShow && !conf.ToolsTest) || HiddenForceShow;
|
||||
ModMain.frmToolsLeft.TextToolsCategory.Visibility = isToolsVisible ? Visibility.Visible : Visibility.Collapsed;
|
||||
if (isToolsVisible) ModMain.frmToolsLeft.TextToolsCategory.Opacity = 0.6;
|
||||
|
||||
// 统计工具页可用项数量
|
||||
var toolsCount = 0;
|
||||
if (!conf.ToolsGameLink)
|
||||
toolsCount += 1;
|
||||
if (!conf.ToolsTest)
|
||||
toolsCount += 1;
|
||||
ModMain.frmToolsLeft.PanItem.Visibility =
|
||||
toolsCount < 2 && !HiddenForceShow ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
|
||||
// 其他入口刷新
|
||||
if (ModMain.frmMain.pageCurrent == FormMain.PageType.InstanceSelect)
|
||||
ModMain.frmSelectRight.BtnEmptyDownload_Loaded();
|
||||
if (ModMain.frmMain.pageCurrent == FormMain.PageType.Launch)
|
||||
ModMain.frmLaunchLeft.RefreshButtonsUI();
|
||||
if (ModMain.frmMain.pageCurrent == FormMain.PageType.InstanceSetup &&
|
||||
ModMain.frmInstanceModDisabled is not null)
|
||||
ModMain.frmInstanceModDisabled.BtnDownload_Loaded();
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
ModBase.Log(
|
||||
ex,
|
||||
"刷新功能隐藏项目失败",
|
||||
ModBase.LogLevel.Feedback,
|
||||
userSummary: Lang.Text("Setup.Ui.Error.OperationFailed"));
|
||||
}
|
||||
}
|
||||
|
||||
// ================= 设置页面协同 =================
|
||||
private void HiddenSetupMain()
|
||||
{
|
||||
var isChecked = (bool)CheckHiddenPageSetup.Checked;
|
||||
CheckHiddenSetupLaunch.Checked = isChecked;
|
||||
CheckHiddenSetupUI.Checked = isChecked;
|
||||
CheckHiddenSetupLauncherLanguage.Checked = isChecked;
|
||||
CheckHiddenSetupGameManage.Checked = isChecked;
|
||||
CheckHiddenLauncherMisc.Checked = isChecked;
|
||||
CheckHiddenSetupJava.Checked = isChecked;
|
||||
CheckHiddenSetupUpdate.Checked = isChecked;
|
||||
CheckHiddenSetupGameLink.Checked = isChecked;
|
||||
CheckHiddenSetupAbout.Checked = isChecked;
|
||||
CheckHiddenSetupFeedback.Checked = isChecked;
|
||||
CheckHiddenSetupLog.Checked = isChecked;
|
||||
}
|
||||
|
||||
// ================= 设置页面协同 =================
|
||||
private void HiddenSetupMain(object sender, bool user)
|
||||
{
|
||||
if (!user)
|
||||
return; // 仅处理用户点击,防止死循环
|
||||
var isChecked = (bool)CheckHiddenPageSetup.Checked;
|
||||
CheckHiddenSetupLaunch.Checked = isChecked;
|
||||
CheckHiddenSetupUI.Checked = isChecked;
|
||||
CheckHiddenSetupLauncherLanguage.Checked = isChecked;
|
||||
CheckHiddenSetupGameManage.Checked = isChecked;
|
||||
CheckHiddenLauncherMisc.Checked = isChecked;
|
||||
CheckHiddenSetupJava.Checked = isChecked;
|
||||
CheckHiddenSetupUpdate.Checked = isChecked;
|
||||
CheckHiddenSetupGameLink.Checked = isChecked;
|
||||
CheckHiddenSetupAbout.Checked = isChecked;
|
||||
CheckHiddenSetupFeedback.Checked = isChecked;
|
||||
CheckHiddenSetupLog.Checked = isChecked;
|
||||
}
|
||||
|
||||
private void HiddenSetupSub(object sender, bool user)
|
||||
{
|
||||
if (!user)
|
||||
return;
|
||||
var conf = Config.Preference.Hide;
|
||||
// 判断是否全部勾选
|
||||
var allChecked = conf.SetupLaunch && conf.SetupUi && conf.SetupLauncherLanguage && conf.SetupJava &&
|
||||
conf.SetupUpdate && conf.SetupGameLink && conf.SetupAbout && conf.SetupFeedback &&
|
||||
conf.SetupLog && conf.SetupLauncherMisc && conf.SetupGameManage;
|
||||
CheckHiddenPageSetup.Checked = allChecked;
|
||||
}
|
||||
|
||||
// ================= 工具页面协同 =================
|
||||
private void HiddenToolsMain(object sender, bool user)
|
||||
{
|
||||
if (!user)
|
||||
return;
|
||||
var isChecked = (bool)CheckHiddenPageTools.Checked;
|
||||
CheckHiddenToolsGameLink.Checked = isChecked;
|
||||
CheckHiddenToolsTest.Checked = isChecked;
|
||||
}
|
||||
|
||||
private void HiddenToolsSub(object sender, bool user)
|
||||
{
|
||||
if (!user)
|
||||
return;
|
||||
var conf = Config.Preference.Hide;
|
||||
var allChecked = conf.ToolsGameLink && conf.ToolsTest;
|
||||
CheckHiddenPageTools.Checked = allChecked;
|
||||
}
|
||||
|
||||
// 警告提示
|
||||
private void HiddenHint(object sender, bool user)
|
||||
{
|
||||
if (ModAnimation.AniControlEnabled == 0 && sender is MyCheckBox checkBox && checkBox.Checked == true)
|
||||
HintService.Hint(Lang.Text("Setup.Ui.FeatureHide.TemporaryHint"));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user