using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher; using Newtonsoft.Json; namespace Ink_Canvas.Helpers.Plugins.BuiltIn { /// /// 超级启动台插件 /// public class SuperLauncherPlugin : PluginBase { #region 插件基本信息 public override string Name => "超级启动台"; public override string Description => "在浮动栏添加一个启动台按钮,可快速启动常用应用程序。"; public override Version Version => new Version(1, 0, 1); public override string Author => "ICC CE 团队"; public override bool IsBuiltIn => true; #endregion #region 插件属性和字段 /// /// 启动台配置 /// public LauncherConfig Config { get; private set; } /// /// 启动台应用程序列表 /// public ObservableCollection LauncherItems { get; private set; } /// /// 启动台按钮 /// private LauncherButton _launcherButton; /// /// 启动台窗口 /// private LauncherWindow _launcherWindow; /// /// 配置文件路径 /// private readonly string _configPath = Path.Combine(App.RootPath, "PluginConfigs", "SuperLauncher.json"); /// /// 标记是否已添加到浮动栏 /// private bool _isAddedToFloatingBar; #endregion #region 插件生命周期 public override void Initialize() { try { base.Initialize(); // 创建配置目录 string configDir = Path.Combine(App.RootPath, "PluginConfigs"); if (!Directory.Exists(configDir)) { Directory.CreateDirectory(configDir); } // 加载配置 LoadConfig(); LogHelper.WriteLogToFile("超级启动台插件已初始化"); } catch (Exception ex) { LogHelper.WriteLogToFile($"初始化超级启动台插件时出错: {ex.Message}", LogHelper.LogType.Error); LogHelper.NewLog(ex); } } public override void Enable() { try { if (IsEnabled) return; // 防止重复启用 // 创建启动台按钮 if (_launcherButton == null) { _launcherButton = new LauncherButton(this); LogHelper.WriteLogToFile("超级启动台按钮已创建"); } // 添加启动台按钮到浮动栏 AddLauncherButtonToFloatingBar(); // 设置启用状态 base.Enable(); // 保存插件配置 SavePluginSettings(); LogHelper.WriteLogToFile("超级启动台插件已启用"); } catch (Exception ex) { LogHelper.WriteLogToFile($"启用超级启动台插件时出错: {ex.Message}", LogHelper.LogType.Error); LogHelper.NewLog(ex); } } public override void Disable() { try { if (!IsEnabled) return; // 防止重复禁用 // 从浮动栏移除启动台按钮 RemoveLauncherButtonFromFloatingBar(); // 如果启动台窗口打开,则关闭 if (_launcherWindow != null && _launcherWindow.IsVisible) { _launcherWindow.Close(); _launcherWindow = null; } // 设置禁用状态 base.Disable(); // 保存插件配置 SavePluginSettings(); LogHelper.WriteLogToFile("超级启动台插件已禁用"); } catch (Exception ex) { LogHelper.WriteLogToFile($"禁用超级启动台插件时出错: {ex.Message}", LogHelper.LogType.Error); LogHelper.NewLog(ex); } } public override UserControl GetSettingsView() { return new LauncherSettingsControl(this); } public override void Cleanup() { // 保存配置 SaveConfig(); // 从浮动栏移除启动台按钮 RemoveLauncherButtonFromFloatingBar(); // 如果启动台窗口打开,则关闭 if (_launcherWindow != null && _launcherWindow.IsVisible) { _launcherWindow.Close(); _launcherWindow = null; } base.Cleanup(); } /// /// 保存插件设置 /// public override void SavePluginSettings() { try { // 确保配置已加载 if (Config == null) { LoadConfig(); } // 更新其他设置,但不更改插件启用状态 // 保存配置 SaveConfig(); LogHelper.WriteLogToFile("超级启动台插件设置已保存"); } catch (Exception ex) { LogHelper.WriteLogToFile($"保存超级启动台插件设置时出错: {ex.Message}", LogHelper.LogType.Error); } } #endregion #region 配置管理 /// /// 加载配置 /// private void LoadConfig() { try { if (File.Exists(_configPath)) { string json = File.ReadAllText(_configPath); Config = JsonConvert.DeserializeObject(json) ?? CreateDefaultConfig(); LauncherItems = new ObservableCollection(Config.Items ?? new List()); // 注意:不再根据配置更改插件启用状态 // 插件状态由PluginManager统一管理 } else { Config = CreateDefaultConfig(); LauncherItems = new ObservableCollection(Config.Items); SaveConfig(); } } catch (Exception ex) { LogHelper.WriteLogToFile($"加载超级启动台配置时出错: {ex.Message}", LogHelper.LogType.Error); Config = CreateDefaultConfig(); LauncherItems = new ObservableCollection(Config.Items); } } /// /// 保存配置 /// public void SaveConfig() { try { // 同步LauncherItems到Config Config.Items = new List(LauncherItems); // 序列化并保存配置 string json = JsonConvert.SerializeObject(Config, Formatting.Indented); File.WriteAllText(_configPath, json); LogHelper.WriteLogToFile("超级启动台配置已保存"); } catch (Exception ex) { LogHelper.WriteLogToFile($"保存超级启动台配置时出错: {ex.Message}", LogHelper.LogType.Error); } } /// /// 创建默认配置 /// private LauncherConfig CreateDefaultConfig() { var config = new LauncherConfig { ButtonPosition = LauncherButtonPosition.Right, // 不再使用IsEnabled,插件状态由PluginManager管理 Items = new List { new LauncherItem { Name = "资源管理器", Path = @"C:\Windows\explorer.exe", IsVisible = true, Position = 0 } } }; return config; } #endregion #region 启动台按钮管理 /// /// 将启动台按钮添加到浮动栏 /// private void AddLauncherButtonToFloatingBar() { try { // 如果已经添加,先移除 if (_isAddedToFloatingBar) { RemoveLauncherButtonFromFloatingBar(); _isAddedToFloatingBar = false; } // 获取主窗口实例 var mainWindow = Application.Current.MainWindow; if (mainWindow == null) { LogHelper.WriteLogToFile("未找到主窗口实例,无法添加启动台按钮", LogHelper.LogType.Error); return; } // 创建启动台按钮 _launcherButton = new LauncherButton(this); var buttonElement = _launcherButton.Element; // 查找浮动栏 var floatingBar = mainWindow.FindName("StackPanelFloatingBar") as Panel; if (floatingBar == null) { // 如果直接查找失败,则尝试遍历可视树查找 Panel floatingBarPanelFromTree = null; FindStackPanelFloatingBar(mainWindow, ref floatingBarPanelFromTree); floatingBar = floatingBarPanelFromTree; } if (floatingBar == null) { LogHelper.WriteLogToFile("未找到浮动栏,无法添加启动台按钮", LogHelper.LogType.Error); return; } // 添加启动台按钮到浮动栏 if (Config.ButtonPosition == LauncherButtonPosition.Left) { floatingBar.Children.Insert(0, buttonElement); LogHelper.WriteLogToFile("启动台按钮已添加到浮动栏左侧"); } else { floatingBar.Children.Add(buttonElement); LogHelper.WriteLogToFile("启动台按钮已添加到浮动栏右侧"); } _isAddedToFloatingBar = true; } catch (Exception ex) { LogHelper.WriteLogToFile($"添加启动台按钮到浮动栏时出错: {ex.Message}", LogHelper.LogType.Error); LogHelper.NewLog(ex); } } /// /// 递归查找StackPanelFloatingBar /// private void FindStackPanelFloatingBar(DependencyObject parent, ref Panel result) { if (parent == null || result != null) return; try { // 检查当前对象是否为我们要找的面板 if (parent is Panel panel && panel.Name == "StackPanelFloatingBar") { result = panel; return; } // 获取子元素数量 int childCount = VisualTreeHelper.GetChildrenCount(parent); // 遍历所有子元素 for (int i = 0; i < childCount; i++) { DependencyObject child = VisualTreeHelper.GetChild(parent, i); FindStackPanelFloatingBar(child, ref result); } } catch (Exception ex) { LogHelper.WriteLogToFile($"查找StackPanelFloatingBar时出错: {ex.Message}", LogHelper.LogType.Error); } } /// /// 从浮动栏移除启动台按钮 /// private void RemoveLauncherButtonFromFloatingBar() { try { if (!_isAddedToFloatingBar || _launcherButton == null) { return; } // 获取主窗口实例 var mainWindow = Application.Current.MainWindow; if (mainWindow == null) { LogHelper.WriteLogToFile("未找到主窗口实例,无法移除启动台按钮", LogHelper.LogType.Error); return; } // 获取按钮元素 var buttonElement = _launcherButton.Element; // 查找浮动栏 var floatingBar = mainWindow.FindName("StackPanelFloatingBar") as Panel; if (floatingBar == null) { // 如果直接查找失败,则尝试遍历可视树查找 Panel floatingBarPanelFromTree = null; FindStackPanelFloatingBar(mainWindow, ref floatingBarPanelFromTree); floatingBar = floatingBarPanelFromTree; } if (floatingBar == null) { LogHelper.WriteLogToFile("未找到浮动栏,无法移除启动台按钮", LogHelper.LogType.Error); return; } // 从浮动栏移除启动台按钮 if (floatingBar.Children.Contains(buttonElement)) { floatingBar.Children.Remove(buttonElement); LogHelper.WriteLogToFile("启动台按钮已从浮动栏移除"); } _isAddedToFloatingBar = false; } catch (Exception ex) { LogHelper.WriteLogToFile($"移除启动台按钮时出错: {ex.Message}", LogHelper.LogType.Error); LogHelper.NewLog(ex); } } /// /// 更新启动台按钮位置 /// public void UpdateButtonPosition() { try { // 如果按钮已添加到浮动栏,重新添加以更新位置 if (_isAddedToFloatingBar) { RemoveLauncherButtonFromFloatingBar(); AddLauncherButtonToFloatingBar(); LogHelper.WriteLogToFile($"启动台按钮位置已更新为: {Config.ButtonPosition}"); } } catch (Exception ex) { LogHelper.WriteLogToFile($"更新启动台按钮位置时出错: {ex.Message}", LogHelper.LogType.Error); LogHelper.NewLog(ex); } } #endregion #region 启动台功能 /// /// 显示启动台窗口 /// /// 按钮在屏幕上的位置 public void ShowLauncherWindow(Point buttonPosition) { try { // 如果窗口已存在,关闭它 if (_launcherWindow != null && _launcherWindow.IsVisible) { _launcherWindow.Close(); _launcherWindow = null; return; } // 创建新的启动台窗口 _launcherWindow = new LauncherWindow(this); // 计算窗口位置,使其位于按钮上方 PositionLauncherWindow(_launcherWindow, buttonPosition); // 显示窗口 _launcherWindow.Show(); } catch (Exception ex) { LogHelper.WriteLogToFile($"显示启动台窗口时出错: {ex.Message}", LogHelper.LogType.Error); } } /// /// 设置启动台窗口位置 /// /// 启动台窗口 /// 按钮在屏幕上的位置 private void PositionLauncherWindow(LauncherWindow window, Point buttonPosition) { // 确保窗口已加载 if (window.ActualWidth == 0 || window.ActualHeight == 0) { window.WindowStartupLocation = WindowStartupLocation.CenterScreen; // 设置窗口加载完成后的位置 window.Loaded += (s, e) => { // 窗口位于按钮上方居中 double left = buttonPosition.X - (window.ActualWidth / 2); double top = buttonPosition.Y - window.ActualHeight - 10; // 在按钮上方留出一些间距 // 确保窗口在屏幕内 left = Math.Max(0, Math.Min(left, SystemParameters.WorkArea.Width - window.ActualWidth)); top = Math.Max(0, Math.Min(top, SystemParameters.WorkArea.Height - window.ActualHeight)); window.Left = left; window.Top = top; }; } else { // 窗口位于按钮上方居中 double left = buttonPosition.X - (window.ActualWidth / 2); double top = buttonPosition.Y - window.ActualHeight - 10; // 在按钮上方留出一些间距 // 确保窗口在屏幕内 left = Math.Max(0, Math.Min(left, SystemParameters.WorkArea.Width - window.ActualWidth)); top = Math.Max(0, Math.Min(top, SystemParameters.WorkArea.Height - window.ActualHeight)); window.Left = left; window.Top = top; } } /// /// 添加应用到启动台 /// /// 启动台项 public void AddLauncherItem(LauncherItem item) { // 如果项目数量已达上限,则不添加 if (LauncherItems.Count >= 40) { MessageBox.Show("启动台项目数量已达上限(40个)!", "提示", MessageBoxButton.OK, MessageBoxImage.Information); return; } // 寻找合适的位置 if (item.Position < 0) { item.Position = FindNextAvailablePosition(); } // 添加项目并保存配置 LauncherItems.Add(item); SaveConfig(); } /// /// 查找下一个可用位置 /// private int FindNextAvailablePosition() { // 获取已使用的位置列表 var usedPositions = new HashSet(); foreach (var item in LauncherItems) { usedPositions.Add(item.Position); } // 查找第一个可用位置 for (int i = 0; i < 40; i++) { if (!usedPositions.Contains(i)) { return i; } } // 如果所有位置都已使用,则返回0 return 0; } #endregion } }