252 lines
12 KiB
C#
252 lines
12 KiB
C#
using Lskj.Control;
|
|
using System;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
|
|
namespace Lskj.Main
|
|
{
|
|
public partial class FrmPersonalSetting : BaseForm
|
|
{
|
|
private MainAppearanceSettings _settings;
|
|
|
|
public FrmPersonalSetting()
|
|
{
|
|
InitializeComponent();
|
|
BuildDesignerControls();
|
|
// 设计器只需要静态控件,不访问本地配置文件或运行时状态。
|
|
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime) return;
|
|
_settings = MainAppearanceSettingsStore.Load();
|
|
LoadSettingsToControls();
|
|
}
|
|
|
|
private void LoadSettingsToControls()
|
|
{
|
|
txtTopColor.Text = _settings.TopMenuBackground;
|
|
txtLeftColor.Text = _settings.SidebarBackground;
|
|
txtLeftSelectColor.Text = _settings.SidebarSelectedBackground;
|
|
numTopFont.Value = Clamp(_settings.TopMenuFontSize, numTopFont.Minimum, numTopFont.Maximum);
|
|
numLeftFont.Value = Clamp(_settings.LeftMenuFontSize, numLeftFont.Minimum, numLeftFont.Maximum);
|
|
// An empty value means "use the program default". Keep the editor
|
|
// visually empty while MainPanelControlEx2 still uses its fallback.
|
|
if (!_settings.TopMenuFontConfigured) numTopFont.Text = string.Empty;
|
|
if (!_settings.LeftMenuFontConfigured) numLeftFont.Text = string.Empty;
|
|
UpdateColorPreview(txtTopColor, pnlTopPreview);
|
|
UpdateColorPreview(txtLeftColor, pnlLeftPreview);
|
|
UpdateColorPreview(txtLeftSelectColor, pnlLeftSelectPreview);
|
|
}
|
|
|
|
private void SaveSettings()
|
|
{
|
|
int ignoredTopFont;
|
|
int ignoredLeftFont;
|
|
MainAppearanceSettingsStore.Save(new MainAppearanceSettings
|
|
{
|
|
TopMenuBackground = MainAppearanceSettingsStore.NormalizeColor(txtTopColor.Text, _settings.TopMenuBackground),
|
|
SidebarBackground = MainAppearanceSettingsStore.NormalizeColor(txtLeftColor.Text, _settings.SidebarBackground),
|
|
SidebarSelectedBackground = MainAppearanceSettingsStore.NormalizeColor(txtLeftSelectColor.Text, _settings.SidebarSelectedBackground),
|
|
TopMenuFontSize = ParseFontEditorValue(numTopFont, MainAppearanceSettingsStore.DefaultTopMenuFontSize),
|
|
LeftMenuFontSize = ParseFontEditorValue(numLeftFont, MainAppearanceSettingsStore.DefaultLeftMenuFontSize),
|
|
TopMenuFontConfigured = TryParseFontEditorValue(numTopFont, out ignoredTopFont),
|
|
LeftMenuFontConfigured = TryParseFontEditorValue(numLeftFont, out ignoredLeftFont)
|
|
});
|
|
DialogResult = DialogResult.OK;
|
|
Close();
|
|
}
|
|
|
|
private void ChooseColor(TextBox textBox, Panel preview)
|
|
{
|
|
Color current = MainAppearanceSettingsStore.ParseColor(textBox.Text, Color.White);
|
|
using (ColorDialog dialog = new ColorDialog { Color = current, FullOpen = true })
|
|
{
|
|
if (dialog.ShowDialog(this) != DialogResult.OK) return;
|
|
textBox.Text = MainAppearanceSettingsStore.FormatColor(dialog.Color);
|
|
UpdateColorPreview(textBox, preview);
|
|
}
|
|
}
|
|
|
|
private static void UpdateColorPreview(TextBox textBox, Panel preview)
|
|
{
|
|
if (preview != null) preview.BackColor = MainAppearanceSettingsStore.ParseColor(textBox.Text, Color.White);
|
|
}
|
|
|
|
private static decimal Clamp(int value, decimal min, decimal max)
|
|
{
|
|
return Math.Min(max, Math.Max(min, value));
|
|
}
|
|
|
|
private static bool TryParseFontEditorValue(NumericUpDown editor, out int value)
|
|
{
|
|
value = 0;
|
|
int parsed;
|
|
if (!int.TryParse((editor == null ? string.Empty : editor.Text ?? string.Empty).Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out parsed)) return false;
|
|
if (parsed < MainAppearanceSettingsStore.MinimumFontSize || parsed > MainAppearanceSettingsStore.MaximumFontSize) return false;
|
|
value = parsed;
|
|
return true;
|
|
}
|
|
|
|
private static int ParseFontEditorValue(NumericUpDown editor, int fallback)
|
|
{
|
|
int value;
|
|
return TryParseFontEditorValue(editor, out value) ? value : fallback;
|
|
}
|
|
|
|
private void txtColor_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (sender == txtTopColor) UpdateColorPreview(txtTopColor, pnlTopPreview);
|
|
else if (sender == txtLeftColor) UpdateColorPreview(txtLeftColor, pnlLeftPreview);
|
|
else if (sender == txtLeftSelectColor) UpdateColorPreview(txtLeftSelectColor, pnlLeftSelectPreview);
|
|
}
|
|
|
|
private void btnTopColor_Click(object sender, EventArgs e) { ChooseColor(txtTopColor, pnlTopPreview); }
|
|
private void btnLeftColor_Click(object sender, EventArgs e) { ChooseColor(txtLeftColor, pnlLeftPreview); }
|
|
private void btnLeftSelectColor_Click(object sender, EventArgs e) { ChooseColor(txtLeftSelectColor, pnlLeftSelectPreview); }
|
|
private void btnSave_Click(object sender, EventArgs e) { SaveSettings(); }
|
|
private void btnCancel_Click(object sender, EventArgs e) { DialogResult = DialogResult.Cancel; Close(); }
|
|
private void btnReset_Click(object sender, EventArgs e) { _settings = MainAppearanceSettingsStore.Defaults(); LoadSettingsToControls(); }
|
|
private void navAppearance_Click(object sender, EventArgs e) { ShowPage(pnlAppearance); }
|
|
private void navFonts_Click(object sender, EventArgs e) { ShowPage(pnlFonts); }
|
|
}
|
|
|
|
internal sealed class MainAppearanceSettings
|
|
{
|
|
public string TopMenuBackground;
|
|
public string SidebarBackground;
|
|
public string SidebarSelectedBackground;
|
|
public int TopMenuFontSize;
|
|
public int LeftMenuFontSize;
|
|
public bool TopMenuFontConfigured;
|
|
public bool LeftMenuFontConfigured;
|
|
}
|
|
|
|
internal static class MainAppearanceSettingsStore
|
|
{
|
|
internal const int DefaultTopMenuFontSize = 9;
|
|
internal const int DefaultLeftMenuFontSize = 12;
|
|
internal const int MinimumFontSize = 8;
|
|
internal const int MaximumFontSize = 24;
|
|
// WinForms uses a separate file so changing the WPF shell settings does not
|
|
// unexpectedly alter the transitional WinForms main panel.
|
|
private const string FileName = "WinFromShellAppearance.ini";
|
|
private const string TopColorKey = "TopMenuBackground=";
|
|
private const string LeftColorKey = "SidebarBackground=";
|
|
private const string LeftSelectedColorKey = "SidebarSelectedBackground=";
|
|
private const string TopFontKey = "TopMenuFontSize=";
|
|
private const string LeftFontKey = "LeftMenuFontSize=";
|
|
|
|
public static MainAppearanceSettings Defaults()
|
|
{
|
|
return new MainAppearanceSettings
|
|
{
|
|
TopMenuBackground = "#1F4B99",
|
|
SidebarBackground = "#272D51",
|
|
SidebarSelectedBackground = "#348ED8",
|
|
TopMenuFontSize = DefaultTopMenuFontSize,
|
|
LeftMenuFontSize = DefaultLeftMenuFontSize,
|
|
TopMenuFontConfigured = false,
|
|
LeftMenuFontConfigured = false
|
|
};
|
|
}
|
|
|
|
public static MainAppearanceSettings Load()
|
|
{
|
|
MainAppearanceSettings result = Defaults();
|
|
try
|
|
{
|
|
string path = GetPath();
|
|
if (!File.Exists(path))
|
|
{
|
|
// Create the WinForms-specific file on first run so the active
|
|
// values are visible and editable from the Debug\Config folder.
|
|
Save(result);
|
|
return result;
|
|
}
|
|
foreach (string raw in File.ReadAllLines(path))
|
|
{
|
|
string line = (raw ?? string.Empty).Trim();
|
|
if (line.StartsWith(TopColorKey, StringComparison.OrdinalIgnoreCase)) result.TopMenuBackground = NormalizeColor(line.Substring(TopColorKey.Length), result.TopMenuBackground);
|
|
else if (line.StartsWith(LeftColorKey, StringComparison.OrdinalIgnoreCase)) result.SidebarBackground = NormalizeColor(line.Substring(LeftColorKey.Length), result.SidebarBackground);
|
|
else if (line.StartsWith(LeftSelectedColorKey, StringComparison.OrdinalIgnoreCase)) result.SidebarSelectedBackground = NormalizeColor(line.Substring(LeftSelectedColorKey.Length), result.SidebarSelectedBackground);
|
|
else if (line.StartsWith(TopFontKey, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
int value;
|
|
if (TryParseFont(line.Substring(TopFontKey.Length), out value)) { result.TopMenuFontSize = value; result.TopMenuFontConfigured = true; }
|
|
}
|
|
else if (line.StartsWith(LeftFontKey, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
int value;
|
|
if (TryParseFont(line.Substring(LeftFontKey.Length), out value)) { result.LeftMenuFontSize = value; result.LeftMenuFontConfigured = true; }
|
|
}
|
|
}
|
|
}
|
|
catch (Exception) { }
|
|
return result;
|
|
}
|
|
|
|
public static void Save(MainAppearanceSettings settings)
|
|
{
|
|
if (settings == null) return;
|
|
string path = GetPath();
|
|
string[] oldLines = new string[0];
|
|
try { if (File.Exists(path)) oldLines = File.ReadAllLines(path); } catch (Exception) { }
|
|
string[] replacements =
|
|
{
|
|
TopColorKey + NormalizeColor(settings.TopMenuBackground, "#1F4B99"),
|
|
LeftColorKey + NormalizeColor(settings.SidebarBackground, "#272D51"),
|
|
LeftSelectedColorKey + NormalizeColor(settings.SidebarSelectedBackground, "#348ED8"),
|
|
TopFontKey + (settings.TopMenuFontConfigured ? settings.TopMenuFontSize.ToString(CultureInfo.InvariantCulture) : string.Empty),
|
|
LeftFontKey + (settings.LeftMenuFontConfigured ? settings.LeftMenuFontSize.ToString(CultureInfo.InvariantCulture) : string.Empty)
|
|
};
|
|
string[] keys = { TopColorKey, LeftColorKey, LeftSelectedColorKey, TopFontKey, LeftFontKey };
|
|
var output = oldLines.ToList();
|
|
for (int i = 0; i < keys.Length; i++)
|
|
{
|
|
int index = output.FindIndex(x => (x ?? string.Empty).Trim().StartsWith(keys[i], StringComparison.OrdinalIgnoreCase));
|
|
if (index >= 0) output[index] = replacements[i]; else output.Add(replacements[i]);
|
|
}
|
|
try
|
|
{
|
|
string dir = Path.GetDirectoryName(path);
|
|
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
|
|
File.WriteAllLines(path, output.ToArray());
|
|
}
|
|
catch (Exception) { }
|
|
}
|
|
|
|
public static string NormalizeColor(string value, string fallback)
|
|
{
|
|
return FormatColor(ParseColor(value, ParseColor(fallback, Color.Black)));
|
|
}
|
|
|
|
public static Color ParseColor(string value, Color fallback)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(value)) return fallback;
|
|
string text = value.Trim();
|
|
if (!text.StartsWith("#", StringComparison.Ordinal) || text.Length != 7) return fallback;
|
|
byte r, g, b;
|
|
if (!byte.TryParse(text.Substring(1, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out r) || !byte.TryParse(text.Substring(3, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out g) || !byte.TryParse(text.Substring(5, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out b)) return fallback;
|
|
return Color.FromArgb(r, g, b);
|
|
}
|
|
|
|
public static string FormatColor(Color color)
|
|
{
|
|
return string.Format(CultureInfo.InvariantCulture, "#{0:X2}{1:X2}{2:X2}", color.R, color.G, color.B);
|
|
}
|
|
|
|
private static bool TryParseFont(string value, out int result)
|
|
{
|
|
result = 0;
|
|
return int.TryParse((value ?? string.Empty).Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out result)
|
|
&& result >= MinimumFontSize && result <= MaximumFontSize;
|
|
}
|
|
|
|
private static string GetPath()
|
|
{
|
|
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config", FileName);
|
|
}
|
|
}
|
|
}
|