초기 커밋: SheetMe 서식생성기 (P0~P5 완료 상태)
레거시 서식생성기(VB.NET WinForms) 대체용 C#/.NET 10 WPF 디자이너. 기준선: 실DB 활성 디자인 1,271건 왕복 의미론 diff 0 / 예외 0, 단위 테스트 49/49. 이 커밋에 함께 포함된 자격증명 분리: - appsettings.json 을 __HOST__/__PASSWORD__ 플레이스홀더로 전환 - 실접속 정보는 appsettings.Development.json 으로 분리(.gitignore 제외, csproj Debug 조건부 복사라 Release 산출물에 실리지 않음) - ConfigLoader 를 환경변수 > Development > appsettings 순 레이어링으로 변경, 미치환 플레이스홀더는 '미설정'으로 간주 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Windows;
|
||||
|
||||
namespace SheetMe.Designer.Services;
|
||||
|
||||
/// <summary>
|
||||
/// 라이트/다크 테마 전환 — App.Resources 의 토큰 사전(Tokens.Dark↔Light)을 교체하면
|
||||
/// {DynamicResource B.*} 를 참조하는 모든 스타일이 라이브 리스킨된다([200]SheetMe SwapThemeTokens 이식).
|
||||
/// 선택은 %LocalAppData%\SheetMe\theme.json 에 보존.
|
||||
/// </summary>
|
||||
public static class ThemeManager
|
||||
{
|
||||
#region Member Fields
|
||||
private static readonly string SettingsPath =
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SheetMe", "theme.json");
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>현재 라이트 테마 여부(기본 다크 — [200]SheetMe 기본값과 동일)</summary>
|
||||
public static bool IsLight { get; private set; }
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
/// <summary>시작 시 저장된 테마 적용</summary>
|
||||
public static void LoadSaved()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(SettingsPath) &&
|
||||
JsonDocument.Parse(File.ReadAllText(SettingsPath)).RootElement.TryGetProperty("theme", out var theme) &&
|
||||
theme.GetString() == "light")
|
||||
{
|
||||
Apply(light: true);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 설정 손상 시 기본(다크) 유지
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>라이트↔다크 토글</summary>
|
||||
public static void Toggle() => Apply(!IsLight);
|
||||
|
||||
/// <summary>테마 적용 — App.Resources 병합 사전에서 토큰 dict 를 찾아 교체</summary>
|
||||
public static void Apply(bool light)
|
||||
{
|
||||
IsLight = light;
|
||||
var dictionaries = Application.Current.Resources.MergedDictionaries;
|
||||
var tokensUri = new Uri($"/Themes/Tokens.{(light ? "Light" : "Dark")}.xaml", UriKind.Relative);
|
||||
for (var i = 0; i < dictionaries.Count; i++)
|
||||
{
|
||||
var source = dictionaries[i].Source?.OriginalString ?? string.Empty;
|
||||
if (source.EndsWith("Tokens.Dark.xaml", StringComparison.OrdinalIgnoreCase) ||
|
||||
source.EndsWith("Tokens.Light.xaml", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
dictionaries[i] = new ResourceDictionary { Source = tokensUri };
|
||||
Save();
|
||||
return;
|
||||
}
|
||||
}
|
||||
dictionaries.Add(new ResourceDictionary { Source = tokensUri });
|
||||
Save();
|
||||
}
|
||||
|
||||
private static void Save()
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(SettingsPath)!);
|
||||
File.WriteAllText(SettingsPath, JsonSerializer.Serialize(new { theme = IsLight ? "light" : "dark" }));
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 저장 실패는 무시(다음 실행 기본 테마)
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user