Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"version": "0.2.0",
"configurations": [
{
// 使用 IntelliSense 找出 C# 调试存在哪些属性
// 将悬停用于现有属性的说明
// 有关详细信息,请访问 https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// 如果已更改目标框架,请确保更新程序路径。
"program": "${workspaceFolder}/src/bin/Debug/net8.0-windows10.0.19041.0/BASpark.dll",
"args": [],
"cwd": "${workspaceFolder}/src",
// 有关“控制台”字段的详细信息,请参阅 https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}
41 changes: 41 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/src/BASpark.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/src/BASpark.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/src/BASpark.csproj"
],
"problemMatcher": "$msCompile"
}
]
}
6 changes: 6 additions & 0 deletions src/BASpark.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,11 @@
<Resource Include="Web\index.html" />
</ItemGroup>

<ItemGroup>
<Content Include="Web\custom-effect-template.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>


</Project>
80 changes: 80 additions & 0 deletions src/ConfigManager.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

namespace BASpark
{
Expand Down Expand Up @@ -51,8 +53,11 @@
public static class ConfigManager
{
private const string RegPath = @"Software\BASpark";
public const string CustomHtmlVirtualHost = "baspark.custom";
public const string CustomHtmlTemplateFileName = "custom-effect-template.html";

public static string ParticleColor { get; set; } = "45,175,255";
public static string CustomHtmlPath { get; set; } = "";
public static bool IsEffectEnabled { get; set; } = true;
public static bool AutoStart { get; set; } = false;
public static bool AgreedToPrivacy { get; set; } = false;
Expand Down Expand Up @@ -122,6 +127,7 @@
ScreenSelections = key.GetValue("ScreenSelections", "")?.ToString() ?? "";
UiLanguage = key.GetValue("UiLanguage", "")?.ToString() ?? "";
ScrollbarVisibility = ParseScrollbarVisibility(key.GetValue("ScrollbarVisibility", "OnScroll")?.ToString());
CustomHtmlPath = key.GetValue("CustomHtmlPath", "")?.ToString() ?? "";
if (!string.IsNullOrWhiteSpace(UiLanguage))
{
Localization.ApplyCulture(UiLanguage);
Expand Down Expand Up @@ -199,6 +205,80 @@
}
}

public static bool IsUsingCustomHtml => TryResolveCustomHtmlUri(out _, out _);

public static bool TryResolveCustomHtmlUri(out string navigateUri, out string folderPath)
{
navigateUri = string.Empty;
folderPath = string.Empty;
if (string.IsNullOrWhiteSpace(CustomHtmlPath))
{
return false;
}

string fullPath;
try
{
fullPath = Path.GetFullPath(CustomHtmlPath.Trim());
}
catch
{
return false;
}

if (!File.Exists(fullPath))
{
return false;
}

string ext = Path.GetExtension(fullPath);
if (!ext.Equals(".html", StringComparison.OrdinalIgnoreCase) &&
!ext.Equals(".htm", StringComparison.OrdinalIgnoreCase))
{
return false;
}

folderPath = Path.GetDirectoryName(fullPath) ?? string.Empty;
if (string.IsNullOrEmpty(folderPath))
{
return false;
}

string fileName = Path.GetFileName(fullPath);
navigateUri = $"https://{CustomHtmlVirtualHost}/{Uri.EscapeDataString(fileName)}";
return true;
}

public static string? GetWebSamplesDirectory()
{
static bool IsWebSamplesDir(string path) =>
Directory.Exists(path) &&
File.Exists(Path.Combine(path, CustomHtmlTemplateFileName));

string besideExe = Path.Combine(AppContext.BaseDirectory, "Web");
if (IsWebSamplesDir(besideExe))
{
return besideExe;
}

string? dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

Check warning on line 264 in src/ConfigManager.cs

View workflow job for this annotation

GitHub Actions / build

'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.
for (int i = 0; i < 8 && !string.IsNullOrEmpty(dir); i++)
{
foreach (string relative in new[] { "Web", Path.Combine("src", "Web") })
{
string candidate = Path.Combine(dir, relative);
if (IsWebSamplesDir(candidate))
{
return candidate;
}
}

dir = Path.GetDirectoryName(dir);
}

return null;
}

public static List<FilterProfile> GetProfiles() => _profiles;

public static FilterProfile? GetActiveProfile()
Expand Down
16 changes: 15 additions & 1 deletion src/ControlPanelWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,20 @@
</Button>
</DockPanel>
<TextBlock x:Name="TxtVisualInputHint" Text="提示:可点击数字输入精确值后可按回车应用" FontSize="11" Foreground="#999" VerticalAlignment="Center" DockPanel.Dock="Right" Margin="0,0,0,8"/>


<TextBlock x:Name="TxtCustomHtmlTitle" Text="自定义 HTML 特效" Foreground="#666" Margin="0,0,0,8" FontSize="12"/>
<TextBox x:Name="TxtCustomHtmlPath" IsReadOnly="True" Height="28" Margin="0,0,0,8" VerticalContentAlignment="Center" FontSize="11" Background="#F8FAFF" BorderBrush="#D6DEE8"/>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<Button x:Name="BtnBrowseCustomHtml" Content="选择 HTML 文件" Click="BrowseCustomHtml_Click" Height="28" Padding="10,0" Margin="0,0,8,0" Background="#F8FAFF" BorderBrush="#45AFFF" Foreground="#45AFFF" Cursor="Hand" FontSize="12">
<Button.Resources><Style TargetType="Border"><Setter Property="CornerRadius" Value="4"/></Style></Button.Resources>
</Button>
<Button x:Name="BtnClearCustomHtml" Content="恢复内置特效" Click="ClearCustomHtml_Click" Height="28" Padding="10,0" Background="White" BorderBrush="#D6DEE8" Cursor="Hand" FontSize="12">
<Button.Resources><Style TargetType="Border"><Setter Property="CornerRadius" Value="4"/></Style></Button.Resources>
</Button>
</StackPanel>
<TextBlock x:Name="TxtCustomHtmlHint" Text="使用自定义 HTML 时,下方内置视觉调节将不可用。" FontSize="11" Foreground="#9BA3AF" Margin="0,0,0,12" TextWrapping="Wrap"/>

<StackPanel x:Name="PanelVisualBuiltIn">
<StackPanel Margin="0,0,0,15">
<DockPanel LastChildFill="False">
<TextBlock x:Name="TxtVisualScale" Text="缩放比例" Foreground="#555" FontSize="13" VerticalAlignment="Center"/>
Expand Down Expand Up @@ -493,6 +506,7 @@
<Button.Resources><Style TargetType="Border"><Setter Property="CornerRadius" Value="4"/></Style></Button.Resources>
</Button>
</StackPanel>
</StackPanel>
</StackPanel>
</Border>
</StackPanel>
Expand Down
82 changes: 82 additions & 0 deletions src/ControlPanelWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
Expand Down Expand Up @@ -80,6 +81,8 @@
private bool _isCheckingUpdate = false;
private bool _suspendLinkedAnimationUiHandlers;
private string _languageAtLoad = Localization.CultureZhCn;
private string _customHtmlPathAtLoad = "";
private string _customHtmlPathPending = "";

public ObservableCollection<FilterProfile> Profiles { get; set; } = new ObservableCollection<FilterProfile>();
public ObservableCollection<string> CurrentProfileProcesses { get; set; } = new ObservableCollection<string>();
Expand All @@ -105,6 +108,7 @@
LoadSettings();
ApplyScrollbarSettings();
UiLocalizer.ApplyControlPanel(this);
UpdateCustomHtmlPathDisplay();
LoadScreenOptions();
CheckAdminStatus();
LoadRemoteNotice();
Expand Down Expand Up @@ -522,6 +526,70 @@
{
RadioScrollbarOnScroll.IsChecked = true;
}

_customHtmlPathPending = ConfigManager.CustomHtmlPath ?? "";
_customHtmlPathAtLoad = _customHtmlPathPending;
UpdateCustomHtmlPathDisplay();
ApplyCustomHtmlUiState();
}

private void UpdateCustomHtmlPathDisplay()
{
TxtCustomHtmlPath.Text = string.IsNullOrWhiteSpace(_customHtmlPathPending)
? Localization.Get("CustomHtml_Builtin")
: _customHtmlPathPending;
}

private void ApplyCustomHtmlUiState()
{
bool usingCustom = !string.IsNullOrWhiteSpace(_customHtmlPathPending) &&
File.Exists(_customHtmlPathPending);
PanelVisualBuiltIn.IsEnabled = !usingCustom;
BtnVisualReset.IsEnabled = !usingCustom;
}

private void BrowseCustomHtml_Click(object sender, RoutedEventArgs e)
{
var dialog = new Microsoft.Win32.OpenFileDialog
{
Filter = Localization.Get("CustomHtml_FileFilter"),
Title = Localization.Get("CustomHtml_SelectTitle")
};

string? webDir = ConfigManager.GetWebSamplesDirectory();
if (!string.IsNullOrEmpty(webDir))
{
dialog.InitialDirectory = webDir;
dialog.FileName = ConfigManager.CustomHtmlTemplateFileName;
}

if (dialog.ShowDialog() == true)
{
if (string.Equals(
Path.GetFileName(dialog.FileName),
"index.html",
StringComparison.OrdinalIgnoreCase))
{
System.Windows.MessageBox.Show(
this,
Localization.Get("CustomHtml_BuiltinIndexWarning"),
Localization.Get("CustomHtml_SelectTitle"),
MessageBoxButton.OK,
MessageBoxImage.Warning);
return;
}

_customHtmlPathPending = dialog.FileName;
UpdateCustomHtmlPathDisplay();
ApplyCustomHtmlUiState();
}
}

private void ClearCustomHtml_Click(object sender, RoutedEventArgs e)
{
_customHtmlPathPending = "";
UpdateCustomHtmlPathDisplay();
ApplyCustomHtmlUiState();
}

private void ApplyScrollbarSettings()
Expand Down Expand Up @@ -1167,6 +1235,12 @@
ConfigManager.Save("AutoStart", autoStartEnabled);
ConfigManager.Save("EnableTelemetry", CheckTelemetry.IsChecked ?? false);
ConfigManager.Save("ParticleColor", ConfigManager.ParticleColor);
bool customHtmlPathChanged = !string.Equals(
_customHtmlPathAtLoad,
_customHtmlPathPending,
StringComparison.OrdinalIgnoreCase);
ConfigManager.CustomHtmlPath = _customHtmlPathPending;
ConfigManager.Save("CustomHtmlPath", _customHtmlPathPending);
ConfigManager.Save("EffectScale", effectScale);
ConfigManager.Save("EffectOpacity", effectOpacity);
ConfigManager.Save("UseLinkedAnimationSpeed", useLinkedAnimationSpeed);
Expand Down Expand Up @@ -1218,6 +1292,13 @@
App.SetAutoStart(ConfigManager.AutoStart);
ApplyAutoStartSettings();

if (customHtmlPathChanged)
{
App.Overlay?.ReloadAllEffectContent();
_customHtmlPathAtLoad = _customHtmlPathPending;
}

ApplyCustomHtmlUiState();
App.Overlay?.UpdateColor(ConfigManager.ParticleColor);
GetUiAnimationSpeeds(out double overlayTrail, out double overlayClick);
App.Overlay?.UpdateEffectSettings(effectScale, effectOpacity, overlayTrail, overlayClick);
Expand Down Expand Up @@ -1250,6 +1331,7 @@
if (languageChanged)
{
UiLocalizer.ApplyControlPanel(this);
UpdateCustomHtmlPathDisplay();
LoadScreenOptions();
ConfigManager.Save("LastNoticeContent", string.Empty);
LoadRemoteNotice();
Expand Down Expand Up @@ -1315,7 +1397,7 @@
string? exePath = AutoStartManager.ResolveExecutablePath(
Environment.ProcessPath,
Process.GetCurrentProcess().MainModule?.FileName,
Assembly.GetExecutingAssembly().Location,

Check warning on line 1400 in src/ControlPanelWindow.xaml.cs

View workflow job for this annotation

GitHub Actions / build

'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.
AppDomain.CurrentDomain.BaseDirectory);

if (string.IsNullOrEmpty(exePath)) return;
Expand Down
Loading
Loading