mirror of
https://github.com/Blinue/Magpie.git
synced 2026-06-24 02:04:10 +00:00
feat: 支持打开配置文件位置
This commit is contained in:
parent
17cc587f65
commit
6ddea9765c
15 changed files with 95 additions and 77 deletions
|
|
@ -419,6 +419,9 @@
|
|||
<Page Include="AboutPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Button.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="ScalingProfilePage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
|
|
|
|||
|
|
@ -192,6 +192,9 @@
|
|||
<Page Include="ShortcutDialog.xaml">
|
||||
<Filter>Controls</Filter>
|
||||
</Page>
|
||||
<Page Include="Button.xaml">
|
||||
<Filter>Styles</Filter>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@
|
|||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<muxc:XamlControlsResources ControlsResourcesVersion="Version2" />
|
||||
<ResourceDictionary Source="ms-appx:///Button.xaml" />
|
||||
<ResourceDictionary Source="ms-appx:///ToggleSwitch.xaml" />
|
||||
<ResourceDictionary Source="ms-appx:///KeyVisual.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
|
|
|||
|
|
@ -16,34 +16,6 @@ using namespace Magpie::Runtime;
|
|||
|
||||
namespace winrt::Magpie::App {
|
||||
|
||||
static hstring GetWorkingDir(bool isPortableMode) {
|
||||
if (isPortableMode) {
|
||||
wchar_t curDir[MAX_PATH];
|
||||
if (!GetCurrentDirectory(MAX_PATH, curDir)) {
|
||||
return L"";
|
||||
}
|
||||
|
||||
std::wstring result = curDir;
|
||||
if (result.back() != L'\\') {
|
||||
result += L'\\';
|
||||
}
|
||||
return result.c_str();
|
||||
} else {
|
||||
wchar_t localAppDataDir[MAX_PATH];
|
||||
HRESULT hr = SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, localAppDataDir);
|
||||
if (FAILED(hr)) {
|
||||
return L"";
|
||||
}
|
||||
|
||||
return StrUtils::ConcatW(
|
||||
localAppDataDir,
|
||||
localAppDataDir[StrUtils::StrLen(localAppDataDir) - 1] == L'\\' ? L"Magpie\\" : L"\\Magpie\\",
|
||||
MAGPIE_VERSION_W,
|
||||
L"\\"
|
||||
).c_str();
|
||||
}
|
||||
}
|
||||
|
||||
static bool LoadBoolSettingItem(
|
||||
const rapidjson::GenericObject<false, rapidjson::Value>& obj,
|
||||
const char* nodeName,
|
||||
|
|
@ -356,12 +328,11 @@ bool AppSettings::Initialize() {
|
|||
Logger& logger = Logger::Get();
|
||||
|
||||
// 若程序所在目录存在配置文件则为便携模式
|
||||
_isPortableMode = Win32Utils::FileExists(CommonSharedConstants::CONFIG_PATH_W);
|
||||
_workingDir = GetWorkingDir(_isPortableMode);
|
||||
_isPortableMode = Win32Utils::FileExists(
|
||||
StrUtils::ConcatW(CommonSharedConstants::CONFIG_DIR, CommonSharedConstants::CONFIG_NAME).c_str());
|
||||
_UpdateConfigPath();
|
||||
|
||||
std::wstring configPath = StrUtils::ConcatW(_workingDir, CommonSharedConstants::CONFIG_PATH_W);
|
||||
|
||||
if (!Win32Utils::FileExists(configPath.c_str())) {
|
||||
if (!Win32Utils::FileExists(_configPath.c_str())) {
|
||||
logger.Info("不存在配置文件");
|
||||
// 只有不存在配置文件时才生成默认缩放模式
|
||||
_SetDefaultScaleModes();
|
||||
|
|
@ -369,7 +340,7 @@ bool AppSettings::Initialize() {
|
|||
}
|
||||
|
||||
std::string configText;
|
||||
if (!Win32Utils::ReadTextFile(configPath.c_str(), configText)) {
|
||||
if (!Win32Utils::ReadTextFile(_configPath.c_str(), configText)) {
|
||||
logger.Error("读取配置文件失败");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -384,8 +355,7 @@ bool AppSettings::Initialize() {
|
|||
}
|
||||
|
||||
bool AppSettings::Save() {
|
||||
std::wstring configDir = StrUtils::ConcatW(_workingDir, L"config");
|
||||
if (!Win32Utils::CreateDir(configDir)) {
|
||||
if (!Win32Utils::CreateDir(_configDir)) {
|
||||
Logger::Get().Error("创建配置文件夹失败");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -474,7 +444,7 @@ bool AppSettings::Save() {
|
|||
|
||||
writer.EndObject();
|
||||
|
||||
if (!Win32Utils::WriteTextFile(StrUtils::ConcatW(_workingDir, CommonSharedConstants::CONFIG_PATH_W).c_str(), json.GetString())) {
|
||||
if (!Win32Utils::WriteTextFile(_configPath.c_str(), json.GetString())) {
|
||||
Logger::Get().Error("保存配置失败");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -490,18 +460,13 @@ void AppSettings::IsPortableMode(bool value) {
|
|||
if (!value) {
|
||||
// 关闭便携模式需删除本地配置文件
|
||||
// 不关心是否成功
|
||||
DeleteFile(StrUtils::ConcatW(_workingDir, CommonSharedConstants::CONFIG_PATH_W).c_str());
|
||||
DeleteFile(StrUtils::ConcatW(_configDir, CommonSharedConstants::CONFIG_NAME).c_str());
|
||||
}
|
||||
|
||||
Logger::Get().Info(value ? "已开启便携模式" : "已关闭便携模式");
|
||||
|
||||
_isPortableMode = value;
|
||||
_workingDir = GetWorkingDir(value);
|
||||
|
||||
// 确保 WorkingDir 存在
|
||||
if (!Win32Utils::CreateDir(_workingDir.c_str(), true)) {
|
||||
Logger::Get().Error(StrUtils::Concat("创建文件夹", StrUtils::UTF16ToUTF8(_workingDir), "失败"));
|
||||
}
|
||||
_UpdateConfigPath();
|
||||
}
|
||||
|
||||
void AppSettings::Theme(uint32_t value) {
|
||||
|
|
@ -772,4 +737,37 @@ void AppSettings::_SetDefaultScaleModes() {
|
|||
}
|
||||
}
|
||||
|
||||
void AppSettings::_UpdateConfigPath() noexcept {
|
||||
if (_isPortableMode) {
|
||||
wchar_t curDir[MAX_PATH];
|
||||
GetCurrentDirectory(MAX_PATH, curDir);
|
||||
|
||||
_configDir = curDir;
|
||||
if (_configDir.back() != L'\\') {
|
||||
_configDir.push_back(L'\\');
|
||||
}
|
||||
_configDir += CommonSharedConstants::CONFIG_DIR;
|
||||
} else {
|
||||
wchar_t localAppDataDir[MAX_PATH];
|
||||
HRESULT hr = SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, localAppDataDir);
|
||||
if (SUCCEEDED(hr)) {
|
||||
_configDir = StrUtils::ConcatW(
|
||||
localAppDataDir,
|
||||
localAppDataDir[StrUtils::StrLen(localAppDataDir) - 1] == L'\\' ? L"Magpie\\" : L"\\Magpie\\",
|
||||
MAGPIE_VERSION_W,
|
||||
L"\\",
|
||||
CommonSharedConstants::CONFIG_DIR
|
||||
);
|
||||
} else {
|
||||
Logger::Get().ComError("SHGetFolderPath 失败", hr);
|
||||
_configDir = CommonSharedConstants::CONFIG_DIR;
|
||||
}
|
||||
}
|
||||
|
||||
_configPath = _configDir + CommonSharedConstants::CONFIG_NAME;
|
||||
|
||||
// 确保 ConfigDir 存在
|
||||
Win32Utils::CreateDir(_configDir.c_str(), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ public:
|
|||
|
||||
bool Save();
|
||||
|
||||
hstring WorkingDir() const noexcept {
|
||||
return _workingDir;
|
||||
const std::wstring& ConfigDir() const noexcept {
|
||||
return _configDir;
|
||||
}
|
||||
|
||||
bool IsPortableMode() const noexcept {
|
||||
|
|
@ -213,8 +213,11 @@ private:
|
|||
void _SetDefaultHotkeys();
|
||||
void _SetDefaultScaleModes();
|
||||
|
||||
void _UpdateConfigPath() noexcept;
|
||||
|
||||
bool _isPortableMode = false;
|
||||
hstring _workingDir;
|
||||
std::wstring _configDir;
|
||||
std::wstring _configPath;
|
||||
|
||||
// 0: 浅色
|
||||
// 1: 深色
|
||||
|
|
|
|||
|
|
@ -60,11 +60,16 @@
|
|||
<ToggleSwitch IsOn="{x:Bind ViewModel.IsShowTrayIcon, Mode=TwoWay}" />
|
||||
</local:SettingItem.ActionContent>
|
||||
</local:SettingItem>
|
||||
<local:SettingItem Title="便携模式"
|
||||
Description="更改用户数据的保存位置">
|
||||
<local:SettingItem Title="便携模式">
|
||||
<local:SettingItem.Icon>
|
||||
<FontIcon Glyph="" />
|
||||
</local:SettingItem.Icon>
|
||||
<local:SettingItem.Description>
|
||||
<StackPanel Orientation="Vertical" Spacing="2">
|
||||
<TextBlock Text="更改配置文件的保存位置" />
|
||||
<HyperlinkButton Content="打开配置文件位置" Click="{x:Bind ViewModel.OpenConfigLocation}" />
|
||||
</StackPanel>
|
||||
</local:SettingItem.Description>
|
||||
<local:SettingItem.ActionContent>
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.IsPortableMode, Mode=TwoWay}" />
|
||||
</local:SettingItem.ActionContent>
|
||||
|
|
|
|||
|
|
@ -82,6 +82,10 @@ void SettingsViewModel::IsPortableMode(bool value) noexcept {
|
|||
_propertyChangedEvent(*this, PropertyChangedEventArgs(L"IsPortableMode"));
|
||||
}
|
||||
|
||||
void SettingsViewModel::OpenConfigLocation() const noexcept {
|
||||
ShellExecute(NULL, L"explore", AppSettings::Get().ConfigDir().c_str(), nullptr, nullptr, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
bool SettingsViewModel::IsShowTrayIcon() const noexcept {
|
||||
return AppSettings::Get().IsShowTrayIcon();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ struct SettingsViewModel : SettingsViewModelT<SettingsViewModel> {
|
|||
bool IsPortableMode() const noexcept;
|
||||
void IsPortableMode(bool value) noexcept;
|
||||
|
||||
void OpenConfigLocation() const noexcept;
|
||||
|
||||
bool IsShowTrayIcon() const noexcept;
|
||||
void IsShowTrayIcon(bool value) noexcept;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ namespace Magpie.App
|
|||
Boolean IsMinimizeAtStartup;
|
||||
Boolean IsMinimizeAtStartupEnabled { get; };
|
||||
Boolean IsPortableMode;
|
||||
void OpenConfigLocation();
|
||||
Boolean IsShowTrayIcon;
|
||||
Boolean IsSimulateExclusiveFullscreen;
|
||||
Boolean IsBreakpointMode;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
<!-- Copied from: https://github.com/microsoft/PowerToys/blob/35bfb0f83e5fc08cc04398e7aa98d77774412d3f/src/settings-ui/Settings.UI/Styles/Button.xaml#L96 -->
|
||||
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:contract7NotPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractNotPresent(Windows.Foundation.UniversalApiContract,7)"
|
||||
xmlns:contract7Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,7)">
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<!-- This style overrides the default style so that all ToggleSwitches are right aligned, with the label on the left -->
|
||||
<Style TargetType="ToggleSwitch">
|
||||
|
|
@ -19,10 +17,10 @@
|
|||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ToggleSwitch">
|
||||
<Grid contract7Present:CornerRadius="{TemplateBinding CornerRadius}"
|
||||
Background="{TemplateBinding Background}"
|
||||
<Grid Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}">
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
|
|
@ -60,10 +58,9 @@
|
|||
Grid.RowSpan="3"
|
||||
Grid.ColumnSpan="3"
|
||||
Margin="0,5"
|
||||
contract7NotPresent:CornerRadius="{StaticResource ControlCornerRadius}"
|
||||
contract7Present:CornerRadius="{TemplateBinding CornerRadius}"
|
||||
Background="{ThemeResource ToggleSwitchContainerBackground}"
|
||||
Control.IsTemplateFocusTarget="True" />
|
||||
Control.IsTemplateFocusTarget="True"
|
||||
CornerRadius="{TemplateBinding CornerRadius}" />
|
||||
<ContentPresenter x:Name="OffContentPresenter"
|
||||
Grid.RowSpan="3"
|
||||
Grid.Column="0"
|
||||
|
|
@ -119,8 +116,8 @@
|
|||
Height="12"
|
||||
Margin="0,0,1,0"
|
||||
HorizontalAlignment="Center"
|
||||
contract7Present:BackgroundSizing="OuterBorderEdge"
|
||||
Background="{ThemeResource ToggleSwitchKnobFillOn}"
|
||||
BackgroundSizing="OuterBorderEdge"
|
||||
BorderBrush="{ThemeResource ToggleSwitchKnobStrokeOn}"
|
||||
CornerRadius="7"
|
||||
Opacity="0"
|
||||
|
|
|
|||
|
|
@ -138,7 +138,6 @@ int XamlApp::Run() {
|
|||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
_uwpApp.SaveSettings();
|
||||
_uwpApp = nullptr;
|
||||
|
||||
_HideTrayIcon();
|
||||
|
|
@ -277,6 +276,8 @@ void XamlApp::_Quit() noexcept {
|
|||
|
||||
if (_hwndMain) {
|
||||
DestroyWindow(_hwndMain);
|
||||
} else {
|
||||
_uwpApp.SaveSettings();
|
||||
}
|
||||
|
||||
PostQuitMessage(0);
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ static constexpr const int CACHE_COMPRESSION_LEVEL = 1;
|
|||
|
||||
static std::wstring GetCacheFileName(std::wstring_view effectName, std::wstring_view hash, UINT flags) {
|
||||
// 缓存文件的命名:{效果名}_{标志位(16进制)}{哈希}
|
||||
return fmt::format(L"{}{}_{:02x}_{}", CommonSharedConstants::CACHE_DIR_W, effectName, flags, hash);
|
||||
return fmt::format(L"{}{}_{:02x}_{}", CommonSharedConstants::CACHE_DIR, effectName, flags, hash);
|
||||
}
|
||||
|
||||
void EffectCacheManager::_AddToMemCache(const std::wstring& cacheFileName, const EffectDesc& desc) {
|
||||
|
|
@ -260,8 +260,8 @@ void EffectCacheManager::Save(std::wstring_view effectName, std::wstring_view ha
|
|||
}
|
||||
}
|
||||
|
||||
if (!Win32Utils::DirExists(CommonSharedConstants::CACHE_DIR_W)) {
|
||||
if (!CreateDirectory(CommonSharedConstants::CACHE_DIR_W, nullptr)) {
|
||||
if (!Win32Utils::DirExists(CommonSharedConstants::CACHE_DIR)) {
|
||||
if (!CreateDirectory(CommonSharedConstants::CACHE_DIR, nullptr)) {
|
||||
Logger::Get().Win32Error("创建 cache 文件夹失败");
|
||||
return;
|
||||
}
|
||||
|
|
@ -272,7 +272,7 @@ void EffectCacheManager::Save(std::wstring_view effectName, std::wstring_view ha
|
|||
|
||||
WIN32_FIND_DATA findData{};
|
||||
HANDLE hFind = Win32Utils::SafeHandle(FindFirstFileEx(
|
||||
StrUtils::ConcatW(CommonSharedConstants::CACHE_DIR_W, L"*").c_str(),
|
||||
StrUtils::ConcatW(CommonSharedConstants::CACHE_DIR, L"*").c_str(),
|
||||
FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_LARGE_FETCH));
|
||||
if (hFind) {
|
||||
do {
|
||||
|
|
@ -285,7 +285,7 @@ void EffectCacheManager::Save(std::wstring_view effectName, std::wstring_view ha
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!DeleteFile(StrUtils::ConcatW(CommonSharedConstants::CACHE_DIR_W, findData.cFileName).c_str())) {
|
||||
if (!DeleteFile(StrUtils::ConcatW(CommonSharedConstants::CACHE_DIR, findData.cFileName).c_str())) {
|
||||
Logger::Get().Win32Error(StrUtils::Concat("删除缓存文件 ",
|
||||
StrUtils::UTF16ToUTF8(findData.cFileName), " 失败"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1470,8 +1470,8 @@ cbuffer __CB2 : register(b1) {
|
|||
|
||||
cbHlsl.append("};\n\n");
|
||||
|
||||
if (MagApp::Get().GetOptions().IsSaveEffectSources() && !Win32Utils::DirExists(CommonSharedConstants::SOURCES_DIR_W)) {
|
||||
if (!CreateDirectory(CommonSharedConstants::SOURCES_DIR_W, nullptr)) {
|
||||
if (MagApp::Get().GetOptions().IsSaveEffectSources() && !Win32Utils::DirExists(CommonSharedConstants::SOURCES_DIR)) {
|
||||
if (!CreateDirectory(CommonSharedConstants::SOURCES_DIR, nullptr)) {
|
||||
Logger::Get().Win32Error("创建 sources 文件夹失败");
|
||||
}
|
||||
}
|
||||
|
|
@ -1487,8 +1487,8 @@ cbuffer __CB2 : register(b1) {
|
|||
|
||||
if (MagApp::Get().GetOptions().IsSaveEffectSources()) {
|
||||
std::wstring fileName = desc.passes.size() == 1
|
||||
? fmt::format(L"{}{}.hlsl", CommonSharedConstants::SOURCES_DIR_W, StrUtils::UTF8ToUTF16(desc.name))
|
||||
: fmt::format(L"{}{}_Pass{}.hlsl", CommonSharedConstants::SOURCES_DIR_W, StrUtils::UTF8ToUTF16(desc.name), id + 1);
|
||||
? fmt::format(L"{}{}.hlsl", CommonSharedConstants::SOURCES_DIR, StrUtils::UTF8ToUTF16(desc.name))
|
||||
: fmt::format(L"{}{}_Pass{}.hlsl", CommonSharedConstants::SOURCES_DIR, StrUtils::UTF8ToUTF16(desc.name), id + 1);
|
||||
|
||||
if (!Win32Utils::WriteFile(fileName.c_str(), source.data(), source.size())) {
|
||||
Logger::Get().Error(fmt::format("保存 Pass{} 源码失败", id + 1));
|
||||
|
|
@ -1525,7 +1525,7 @@ UINT EffectCompiler::Compile(
|
|||
desc.name = StrUtils::UTF16ToUTF8(effectName);
|
||||
desc.flags = flags;
|
||||
|
||||
std::wstring fileName = StrUtils::ConcatW(CommonSharedConstants::EFFECTS_DIR_W, effectName, L".hlsl");
|
||||
std::wstring fileName = StrUtils::ConcatW(CommonSharedConstants::EFFECTS_DIR, effectName, L".hlsl");
|
||||
|
||||
std::string source;
|
||||
if (!Win32Utils::ReadTextFile(fileName.c_str(), source)) {
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ bool OverlayDrawer::Initialize() {
|
|||
static std::vector<BYTE> fontData;
|
||||
if (fontData.empty()) {
|
||||
if (!Win32Utils::ReadFile(
|
||||
StrUtils::ConcatW(CommonSharedConstants::ASSETS_DIR_W, L"NotoSansSC-Regular.otf").c_str(),
|
||||
StrUtils::ConcatW(CommonSharedConstants::ASSETS_DIR, L"NotoSansSC-Regular.otf").c_str(),
|
||||
fontData
|
||||
)) {
|
||||
Logger::Get().Error("读取字体文件失败");
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ struct CommonSharedConstants {
|
|||
static constexpr const COLORREF DARK_TINT_COLOR = RGB(32, 32, 32);
|
||||
|
||||
static constexpr const char* LOG_PATH = "logs\\magpie.log";
|
||||
static constexpr const char* CONFIG_PATH = "config\\config.json";
|
||||
static constexpr const wchar_t* CONFIG_PATH_W = L"config\\config.json";
|
||||
static constexpr const wchar_t* SOURCES_DIR_W = L"sources\\";
|
||||
static constexpr const wchar_t* EFFECTS_DIR_W = L"effects\\";
|
||||
static constexpr const wchar_t* ASSETS_DIR_W = L"assets\\";
|
||||
static constexpr const wchar_t* CACHE_DIR_W = L"cache\\";
|
||||
static constexpr const wchar_t* CONFIG_DIR = L"config\\";
|
||||
static constexpr const wchar_t* CONFIG_NAME = L"config.json";
|
||||
static constexpr const wchar_t* SOURCES_DIR = L"sources\\";
|
||||
static constexpr const wchar_t* EFFECTS_DIR = L"effects\\";
|
||||
static constexpr const wchar_t* ASSETS_DIR = L"assets\\";
|
||||
static constexpr const wchar_t* CACHE_DIR = L"cache\\";
|
||||
|
||||
static constexpr const wchar_t* OPTION_MINIMIZE_TO_TRAY_AT_STARTUP = L"-t";
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue