2026-01-10 17:31:55 +08:00
|
|
|
|
using Ink_Canvas;
|
2026-01-02 01:35:22 +08:00
|
|
|
|
using iNKORE.UI.WPF.Helpers;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Windows;
|
|
|
|
|
|
using System.Windows.Controls;
|
|
|
|
|
|
using System.Windows.Input;
|
|
|
|
|
|
using System.Windows.Media;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Ink_Canvas.Windows.SettingsViews
|
|
|
|
|
|
{
|
2026-01-10 17:31:55 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设置面板基类,提供通用的辅助方法
|
|
|
|
|
|
/// </summary>
|
2026-01-02 01:35:22 +08:00
|
|
|
|
public abstract class SettingsPanelBase : UserControl
|
|
|
|
|
|
{
|
|
|
|
|
|
protected bool _isLoaded = false;
|
|
|
|
|
|
|
|
|
|
|
|
public SettingsPanelBase()
|
|
|
|
|
|
{
|
|
|
|
|
|
Loaded += SettingsPanelBase_Loaded;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void SettingsPanelBase_Loaded(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
LoadSettings();
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 添加触摸支持
|
2026-01-02 01:35:22 +08:00
|
|
|
|
EnableTouchSupport();
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 应用主题(如果面板有 ApplyTheme 方法)
|
2026-01-02 01:35:22 +08:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var applyThemeMethod = this.GetType().GetMethod("ApplyTheme",
|
|
|
|
|
|
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
|
|
|
|
|
if (applyThemeMethod != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
applyThemeMethod.Invoke(this, null);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
2026-01-10 17:31:55 +08:00
|
|
|
|
System.Diagnostics.Debug.WriteLine($"SettingsPanelBase 应用主题时出错: {ex.Message}");
|
2026-01-02 01:35:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
_isLoaded = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 为面板中的所有交互控件启用触摸支持
|
|
|
|
|
|
/// </summary>
|
2026-01-02 01:35:22 +08:00
|
|
|
|
protected virtual void EnableTouchSupport()
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 延迟执行,确保所有控件都已加载
|
2026-01-02 01:35:22 +08:00
|
|
|
|
Dispatcher.BeginInvoke(new Action(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
EnableTouchSupportForControls(this);
|
|
|
|
|
|
}), System.Windows.Threading.DispatcherPriority.Loaded);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
2026-01-10 17:31:55 +08:00
|
|
|
|
System.Diagnostics.Debug.WriteLine($"启用触摸支持时出错: {ex.Message}");
|
2026-01-02 01:35:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 为控件树中的所有交互控件启用触摸支持
|
|
|
|
|
|
/// </summary>
|
2026-01-02 01:35:22 +08:00
|
|
|
|
private void EnableTouchSupportForControls(DependencyObject parent)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (parent == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
var child = VisualTreeHelper.GetChild(parent, i);
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 为 Border 控件(ToggleSwitch、选项按钮等)启用触摸支持
|
2026-01-02 01:35:22 +08:00
|
|
|
|
if (child is Border border)
|
|
|
|
|
|
{
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 检查是否是交互控件(有 Tag 或 Cursor 为 Hand)
|
2026-01-02 01:35:22 +08:00
|
|
|
|
if (border.Tag != null || border.Cursor == Cursors.Hand)
|
|
|
|
|
|
{
|
|
|
|
|
|
border.IsManipulationEnabled = true;
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 添加触摸事件支持,将触摸事件转换为鼠标事件
|
2026-01-02 01:35:22 +08:00
|
|
|
|
border.TouchDown += Border_TouchDown;
|
|
|
|
|
|
border.PreviewTouchDown += Border_PreviewTouchDown;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 为 Button 控件启用触摸支持
|
2026-01-02 01:35:22 +08:00
|
|
|
|
else if (child is Button button)
|
|
|
|
|
|
{
|
|
|
|
|
|
button.IsManipulationEnabled = true;
|
|
|
|
|
|
}
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 为 ComboBox 启用触摸支持
|
2026-01-02 01:35:22 +08:00
|
|
|
|
else if (child is ComboBox comboBox)
|
|
|
|
|
|
{
|
|
|
|
|
|
comboBox.IsManipulationEnabled = true;
|
|
|
|
|
|
}
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 为 Slider 启用触摸支持
|
2026-01-02 01:35:22 +08:00
|
|
|
|
else if (child is Slider slider)
|
|
|
|
|
|
{
|
|
|
|
|
|
slider.IsManipulationEnabled = true;
|
|
|
|
|
|
}
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 为 TextBox 启用触摸支持
|
2026-01-02 01:35:22 +08:00
|
|
|
|
else if (child is TextBox textBox)
|
|
|
|
|
|
{
|
|
|
|
|
|
textBox.IsManipulationEnabled = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 递归处理子元素
|
2026-01-02 01:35:22 +08:00
|
|
|
|
EnableTouchSupportForControls(child);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Border 触摸按下事件处理
|
|
|
|
|
|
/// </summary>
|
2026-01-02 01:35:22 +08:00
|
|
|
|
private void Border_TouchDown(object sender, TouchEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
var border = sender as Border;
|
|
|
|
|
|
if (border == null) return;
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 获取触摸点位置
|
2026-01-02 01:35:22 +08:00
|
|
|
|
var touchPoint = e.GetTouchPoint(border);
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 创建模拟的鼠标事件
|
2026-01-02 01:35:22 +08:00
|
|
|
|
var mouseButtonEventArgs = new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, MouseButton.Left)
|
|
|
|
|
|
{
|
|
|
|
|
|
RoutedEvent = UIElement.MouseLeftButtonDownEvent,
|
|
|
|
|
|
Source = border
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 触发鼠标按下事件
|
2026-01-02 01:35:22 +08:00
|
|
|
|
border.RaiseEvent(mouseButtonEventArgs);
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 捕获触摸设备
|
2026-01-02 01:35:22 +08:00
|
|
|
|
border.CaptureTouch(e.TouchDevice);
|
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Border 预览触摸按下事件处理
|
|
|
|
|
|
/// </summary>
|
2026-01-02 01:35:22 +08:00
|
|
|
|
private void Border_PreviewTouchDown(object sender, TouchEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
var border = sender as Border;
|
|
|
|
|
|
if (border == null) return;
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 获取触摸点位置
|
2026-01-02 01:35:22 +08:00
|
|
|
|
var touchPoint = e.GetTouchPoint(border);
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 创建模拟的鼠标事件
|
2026-01-02 01:35:22 +08:00
|
|
|
|
var mouseButtonEventArgs = new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, MouseButton.Left)
|
|
|
|
|
|
{
|
|
|
|
|
|
RoutedEvent = UIElement.PreviewMouseLeftButtonDownEvent,
|
|
|
|
|
|
Source = border
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 触发预览鼠标按下事件
|
2026-01-02 01:35:22 +08:00
|
|
|
|
border.RaiseEvent(mouseButtonEventArgs);
|
|
|
|
|
|
|
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 加载设置到UI - 子类需要实现
|
|
|
|
|
|
/// </summary>
|
2026-01-02 01:35:22 +08:00
|
|
|
|
public abstract void LoadSettings();
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 查找ToggleSwitch控件
|
|
|
|
|
|
/// </summary>
|
2026-01-02 01:35:22 +08:00
|
|
|
|
protected Border FindToggleSwitch(string name)
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.FindDescendantByName(name) as Border;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设置ToggleSwitch状态
|
|
|
|
|
|
/// </summary>
|
2026-01-02 01:35:22 +08:00
|
|
|
|
protected void SetToggleSwitchState(Border toggleSwitch, bool isOn)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (toggleSwitch == null) return;
|
|
|
|
|
|
toggleSwitch.Background = isOn
|
2026-01-10 17:31:55 +08:00
|
|
|
|
? new SolidColorBrush(Color.FromRgb(53, 132, 228))
|
2026-02-06 22:06:50 +08:00
|
|
|
|
: (ThemeHelper.IsDarkTheme ? ThemeHelper.GetButtonBackgroundBrush() : new SolidColorBrush(Color.FromRgb(225, 225, 225)));
|
2026-01-02 01:35:22 +08:00
|
|
|
|
var innerBorder = toggleSwitch.Child as Border;
|
|
|
|
|
|
if (innerBorder != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
innerBorder.HorizontalAlignment = isOn ? HorizontalAlignment.Right : HorizontalAlignment.Left;
|
2026-02-06 22:06:50 +08:00
|
|
|
|
innerBorder.Background = new SolidColorBrush(Colors.White);
|
2026-01-02 01:35:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 通用的ToggleSwitch点击事件处理
|
|
|
|
|
|
/// </summary>
|
2026-01-02 01:35:22 +08:00
|
|
|
|
protected virtual void ToggleSwitch_Click(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!_isLoaded) return;
|
|
|
|
|
|
|
|
|
|
|
|
var border = sender as Border;
|
|
|
|
|
|
if (border == null) return;
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
bool isOn = border.Background.ToString() == "#FF3584E4";
|
2026-01-02 01:35:22 +08:00
|
|
|
|
bool newState = !isOn;
|
|
|
|
|
|
SetToggleSwitchState(border, newState);
|
|
|
|
|
|
|
|
|
|
|
|
string tag = border.Tag?.ToString();
|
|
|
|
|
|
if (string.IsNullOrEmpty(tag)) return;
|
|
|
|
|
|
|
|
|
|
|
|
HandleToggleSwitchChange(tag, newState);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 处理ToggleSwitch变化 - 子类需要实现
|
|
|
|
|
|
/// </summary>
|
2026-01-02 01:35:22 +08:00
|
|
|
|
protected abstract void HandleToggleSwitchChange(string tag, bool newState);
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 处理选项按钮变化 - 子类可以重写
|
|
|
|
|
|
/// </summary>
|
2026-01-02 01:35:22 +08:00
|
|
|
|
protected virtual void HandleOptionButtonChange(object sender, string tag)
|
|
|
|
|
|
{
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 默认实现:清除同组其他按钮的选中状态
|
2026-01-02 01:35:22 +08:00
|
|
|
|
var border = sender as Border;
|
|
|
|
|
|
if (border == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
string[] parts = tag.Split('_');
|
|
|
|
|
|
if (parts.Length >= 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
string group = parts[0];
|
|
|
|
|
|
string value = parts[1];
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
// 清除同组其他按钮的选中状态
|
2026-01-02 01:35:22 +08:00
|
|
|
|
var parent = border.Parent as Panel;
|
|
|
|
|
|
if (parent != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var child in parent.Children)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (child is Border childBorder && childBorder != border)
|
|
|
|
|
|
{
|
|
|
|
|
|
string childTag = childBorder.Tag?.ToString();
|
|
|
|
|
|
if (!string.IsNullOrEmpty(childTag) && childTag.StartsWith(group + "_"))
|
|
|
|
|
|
{
|
|
|
|
|
|
childBorder.Background = new SolidColorBrush(Colors.Transparent);
|
|
|
|
|
|
var textBlock = childBorder.Child as TextBlock;
|
|
|
|
|
|
if (textBlock != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
textBlock.FontWeight = FontWeights.Normal;
|
2026-02-07 14:02:26 +08:00
|
|
|
|
textBlock.Foreground = ThemeHelper.GetTextPrimaryBrush();
|
2026-01-02 01:35:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-07 14:02:26 +08:00
|
|
|
|
bool isDarkTheme = ThemeHelper.IsDarkTheme;
|
|
|
|
|
|
var selectedBrush = isDarkTheme ? new SolidColorBrush(Color.FromRgb(25, 25, 25)) : new SolidColorBrush(Color.FromRgb(225, 225, 225));
|
|
|
|
|
|
border.Background = selectedBrush;
|
2026-01-02 01:35:22 +08:00
|
|
|
|
var currentTextBlock = border.Child as TextBlock;
|
|
|
|
|
|
if (currentTextBlock != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
currentTextBlock.FontWeight = FontWeights.Bold;
|
2026-02-07 14:02:26 +08:00
|
|
|
|
currentTextBlock.Foreground = ThemeHelper.GetTextPrimaryBrush();
|
2026-01-02 01:35:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HandleOptionChange(group, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-10 17:31:55 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 处理选项变化 - 子类需要实现
|
|
|
|
|
|
/// </summary>
|
2026-01-02 01:35:22 +08:00
|
|
|
|
protected abstract void HandleOptionChange(string group, string value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|