From 6a8220e7ebd566e15bb7277031ad3b0968c5414c Mon Sep 17 00:00:00 2001 From: kriastans Date: Sun, 1 Sep 2024 23:13:43 +0800 Subject: [PATCH] [update] ToolbarV2 --- InkCanvasForClass/InkCanvasForClass.csproj | 2 + .../InkCanvasForClass.csproj.user | 6 + InkCanvasForClass/MainWindow.xaml.cs | 3 + InkCanvasForClass/MainWindow_cs/MW_Timer.cs | 5 +- .../Popups/FloatingToolBarV2.xaml | 184 +++++++++ .../Popups/FloatingToolBarV2.xaml.cs | 361 ++++++++++++++++++ .../Resources/Icons-png/icc-toolbar-v2.png | Bin 0 -> 10643 bytes 7 files changed, 559 insertions(+), 2 deletions(-) create mode 100644 InkCanvasForClass/Popups/FloatingToolBarV2.xaml create mode 100644 InkCanvasForClass/Popups/FloatingToolBarV2.xaml.cs create mode 100644 InkCanvasForClass/Resources/Icons-png/icc-toolbar-v2.png diff --git a/InkCanvasForClass/InkCanvasForClass.csproj b/InkCanvasForClass/InkCanvasForClass.csproj index 0046d07..8fc2578 100644 --- a/InkCanvasForClass/InkCanvasForClass.csproj +++ b/InkCanvasForClass/InkCanvasForClass.csproj @@ -226,6 +226,7 @@ + @@ -533,6 +534,7 @@ + diff --git a/InkCanvasForClass/InkCanvasForClass.csproj.user b/InkCanvasForClass/InkCanvasForClass.csproj.user index 9e6bd27..8543433 100644 --- a/InkCanvasForClass/InkCanvasForClass.csproj.user +++ b/InkCanvasForClass/InkCanvasForClass.csproj.user @@ -17,6 +17,9 @@ Code + + Code + Code @@ -46,6 +49,9 @@ Designer + + Designer + Designer diff --git a/InkCanvasForClass/MainWindow.xaml.cs b/InkCanvasForClass/MainWindow.xaml.cs index 0e8cf0e..6999a14 100644 --- a/InkCanvasForClass/MainWindow.xaml.cs +++ b/InkCanvasForClass/MainWindow.xaml.cs @@ -270,6 +270,9 @@ namespace Ink_Canvas { new HWND(new WindowInteropHelper(this).Handle) }); + var ftv2 = new FloatingToolBarV2(); + ftv2.Show(); + UpdateIndexInfoDisplay(); } diff --git a/InkCanvasForClass/MainWindow_cs/MW_Timer.cs b/InkCanvasForClass/MainWindow_cs/MW_Timer.cs index 6b6c46d..8bf1e67 100644 --- a/InkCanvasForClass/MainWindow_cs/MW_Timer.cs +++ b/InkCanvasForClass/MainWindow_cs/MW_Timer.cs @@ -195,7 +195,9 @@ namespace Ink_Canvas { if (isFloatingBarChangingHideMode) return; try { var windowProcessName = ForegroundWindowInfo.ProcessName(); + Trace.WriteLine(windowProcessName); var windowTitle = ForegroundWindowInfo.WindowTitle(); + Trace.WriteLine(windowTitle); //LogHelper.WriteLogToFile("windowTitle | " + windowTitle + " | windowProcessName | " + windowProcessName); if (windowProcessName == "EasiNote") { @@ -207,8 +209,7 @@ namespace Ink_Canvas { Trace.WriteLine(ForegroundWindowInfo.ProcessPath()); Trace.WriteLine(version); Trace.WriteLine(prodName); - if (version.StartsWith("5.") && Settings.Automation.IsAutoFoldInEasiNote && (!(windowTitle.Length == 0 && ForegroundWindowInfo.WindowRect().Height < 500) || - !Settings.Automation.IsAutoFoldInEasiNoteIgnoreDesktopAnno)) { // EasiNote5 + if (version.StartsWith("5.") && Settings.Automation.IsAutoFoldInEasiNote ) { // EasiNote5 if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); } else if (version.StartsWith("3.") && Settings.Automation.IsAutoFoldInEasiNote3) { // EasiNote3 if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); diff --git a/InkCanvasForClass/Popups/FloatingToolBarV2.xaml b/InkCanvasForClass/Popups/FloatingToolBarV2.xaml new file mode 100644 index 0000000..9b0e5db --- /dev/null +++ b/InkCanvasForClass/Popups/FloatingToolBarV2.xaml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/InkCanvasForClass/Popups/FloatingToolBarV2.xaml.cs b/InkCanvasForClass/Popups/FloatingToolBarV2.xaml.cs new file mode 100644 index 0000000..004ad23 --- /dev/null +++ b/InkCanvasForClass/Popups/FloatingToolBarV2.xaml.cs @@ -0,0 +1,361 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace Ink_Canvas +{ + + public enum FloatingBarItemType { + Button, + StateButton, + Separator + } + + public class FloatingBarItem { + public string Name { get; set; } + public ImageSource IconSource { get; set; } + public bool Selected { get; set; } = false; + public bool IsVisible { get; set; } = true; + public string IconSourceResourceKey { get; set; } + public FloatingBarItemType Type { get; set; } + public MainWindow.ICCToolsEnum ToolType { get; set; } + public SolidColorBrush _backgroundBrush { + get { + if (Selected) return new SolidColorBrush(Color.FromRgb(37, 99, 235)); + return new SolidColorBrush(Colors.Transparent); + } + } + public Visibility _itemVisibility { + get { + if (!IsVisible) return Visibility.Collapsed; + return Type != FloatingBarItemType.Separator ? Visibility.Visible : Visibility.Collapsed; + } + } + public Visibility _separatorVisibility { + get { + if (!IsVisible) return Visibility.Collapsed; + return Type != FloatingBarItemType.Separator ? Visibility.Collapsed : Visibility.Visible; + } + } + } + + /// + /// FloatingToolBarV2.xaml 的交互逻辑 + /// + public partial class FloatingToolBarV2 : Window { + + public FloatingToolBarV2() { + InitializeComponent(); + + ToolBarItemsControl.ItemsSource = ToolbarItems; + //var clonedDrawing = (FindResource("CursorIcon") as DrawingImage).Clone(); + //((clonedDrawing.Drawing as DrawingGroup).Children[0] as + // GeometryDrawing).Brush = new SolidColorBrush(Colors.Black); + ToolbarItems.Add(new FloatingBarItem() { + Name = "Cursor", + IconSource = FindResource("CursorIcon") as DrawingImage, + IconSourceResourceKey = "CursorIcon", + IsVisible = true, + Selected = false, + ToolType = MainWindow.ICCToolsEnum.CursorMode, + Type = FloatingBarItemType.StateButton, + }); + ToolbarItems.Add(new FloatingBarItem() { + Name = "Pen", + IconSource = FindResource("PenIcon") as DrawingImage, + IconSourceResourceKey = "PenIcon", + IsVisible = true, + Selected = false, + ToolType = MainWindow.ICCToolsEnum.PenMode, + Type = FloatingBarItemType.StateButton, + }); + ToolbarItems.Add(new FloatingBarItem() { + Name = "Clear", + IconSource = FindResource("TrashBinIcon") as DrawingImage, + IconSourceResourceKey = "TrashBinIcon", + IsVisible = true, + Selected = false, + Type = FloatingBarItemType.Button, + }); + ToolbarItems.Add(new FloatingBarItem() { + Name = "SeparatorA", + IsVisible = true, + Type = FloatingBarItemType.Separator, + }); + ToolbarItems.Add(new FloatingBarItem() { + Name = "Eraser", + IconSource = FindResource("EraserIcon") as DrawingImage, + IconSourceResourceKey = "EraserIcon", + IsVisible = true, + Selected = false, + ToolType = MainWindow.ICCToolsEnum.EraseByGeometryMode, + Type = FloatingBarItemType.StateButton, + }); + ToolbarItems.Add(new FloatingBarItem() { + Name = "ShapeDrawing", + IconSource = FindResource("ShapesIcon") as DrawingImage, + IconSourceResourceKey = "ShapesIcon", + IsVisible = true, + Selected = false, + Type = FloatingBarItemType.Button, + }); + ToolbarItems.Add(new FloatingBarItem() { + Name = "Select", + IconSource = FindResource("SelectIcon") as DrawingImage, + IconSourceResourceKey = "SelectIcon", + IsVisible = true, + Selected = false, + ToolType = MainWindow.ICCToolsEnum.LassoMode, + Type = FloatingBarItemType.StateButton, + }); + ToolbarItems.Add(new FloatingBarItem() { + Name = "SeparatorB", + IsVisible = true, + Type = FloatingBarItemType.Separator, + }); + ToolbarItems.Add(new FloatingBarItem() { + Name = "Undo", + IconSource = FindResource("UndoIcon") as DrawingImage, + IconSourceResourceKey = "UndoIcon", + IsVisible = true, + Selected = false, + Type = FloatingBarItemType.Button, + }); + ToolbarItems.Add(new FloatingBarItem() { + Name = "Redo", + IconSource = FindResource("RedoIcon") as DrawingImage, + IconSourceResourceKey = "RedoIcon", + IsVisible = true, + Selected = false, + Type = FloatingBarItemType.Button, + }); + ToolbarItems.Add(new FloatingBarItem() { + Name = "SeparatorC", + IsVisible = true, + Type = FloatingBarItemType.Separator, + }); + ToolbarItems.Add(new FloatingBarItem() { + Name = "Gesture", + IconSource = FindResource("GestureIcon") as DrawingImage, + IconSourceResourceKey = "GestureIcon", + IsVisible = true, + Selected = false, + Type = FloatingBarItemType.Button, + }); + ToolbarItems.Add(new FloatingBarItem() { + Name = "Menu", + IconSource = FindResource("MoreIcon") as DrawingImage, + IconSourceResourceKey = "MoreIcon", + IsVisible = true, + Selected = false, + Type = FloatingBarItemType.Button, + }); + ToolbarItems.Add(new FloatingBarItem() { + Name = "Fold", + IconSource = FindResource("FoldIcon") as DrawingImage, + IconSourceResourceKey = "FoldIcon", + IsVisible = true, + Selected = false, + Type = FloatingBarItemType.Button, + }); + + ReMeasureToolBar(); + UpdateToolBarSelectedTool(MainWindow.ICCToolsEnum.CursorMode); + UpdateToolBarVariant(1); + + double widthInDevicePixels = GetSystemMetrics(0); // SM_CXSCREEN + double widthInDIP = SystemParameters.WorkArea.Right; // Device independent pixels. + double scalingFactor = widthInDIP/widthInDevicePixels; + ScalingFactor = scalingFactor; + + } + + private double ScalingFactor; + + public ObservableCollection ToolbarItems { get; set; } = + new ObservableCollection(); + + private Grid _mouseDownButton = null; + private bool _isMouseDownHeadIcon = false; + + private double CaculateToolBarWindowWidth(Collection toolbarItems) { + // ------------------------------------------------------// + var containerMargin = 4D; // 内容StackPanel的Margin + var itemWidth = 42D; // 按钮宽度 + var itemsSpacing = 2D; // 按钮之间的间距 + var headIconSpacingRight = 4D; // icc图标的右间距 + var separatorWidth = 1D; // 分隔符宽度 + var separatorSpacing = 3D; // 分隔符左右的间距 + // ------------------------------------------------------// + + var _width = containerMargin * 2 + itemWidth + headIconSpacingRight - itemsSpacing; + foreach (var i in toolbarItems) { + if (!i.IsVisible) continue; + if (i.Type != FloatingBarItemType.Separator) _width += itemsSpacing + itemWidth; + else _width += separatorSpacing + separatorWidth + separatorSpacing - itemsSpacing; + } + + return _width; + } + + /// + /// 修改工具栏的变体 + /// + /// 0为全长,1为鼠标模式下变体,2为迷你,3为仅小图标 + private void UpdateToolBarVariant(int variant) { + IEnumerable items; + if (variant == 0) items = ToolbarItems.AsEnumerable(); + else if (variant == 1) + items = ToolbarItems.Where((item, i) => (new string[] { + "Cursor", "Pen", "Clear", "SeparatorC", "Gesture", "Menu", "Fold" + }).Contains(item.Name)); + else if (variant == 2) + items = ToolbarItems.Where((item, i) => (new string[] { + "Cursor", "Pen", "Clear" + }).Contains(item.Name)); + else throw new NotImplementedException(); + + foreach (var fi in ToolbarItems) { + fi.IsVisible = items.Contains(fi); + } + + CollectionViewSource.GetDefaultView(ToolbarItems).Refresh(); + ReMeasureToolBar(); + } + + private void UpdateToolBarSelectedTool(MainWindow.ICCToolsEnum type) { + var _i = ToolbarItems.Where((item, i) => + item.Type == FloatingBarItemType.StateButton && + item.ToolType == type).Single(); + var nowSelected = ToolbarItems.Where((item, i) => + item.Selected); + if (nowSelected.Any() && nowSelected.Count()==1 && _i == nowSelected.Single()) return; + + foreach (var fi in ToolbarItems) { + if (fi.Type == FloatingBarItemType.Separator) continue; + fi.Selected = false; + fi.IconSource = FindResource(fi.IconSourceResourceKey) as ImageSource; + } + + _i.Selected = true; + var clonedIcon = _i.IconSource.Clone() as DrawingImage; + foreach (var d in (clonedIcon.Drawing as DrawingGroup).Children) + ((GeometryDrawing)d).Brush = new SolidColorBrush(Colors.White); + _i.IconSource = clonedIcon; + + CollectionViewSource.GetDefaultView(ToolbarItems).Refresh(); + } + + private void ReMeasureToolBar() { + var barWidth = CaculateToolBarWindowWidth(ToolbarItems); + ToolBarV2Grid.Width = barWidth; + Width = barWidth + 6 * 2; // 6是工具栏和窗口的Margin + Height = 48 + 6 * 2; // 48是工具栏高度 + } + + private void OnToolSelectionChanged(FloatingBarItem sender) { + if (sender.Selected && sender.ToolType != MainWindow.ICCToolsEnum.CursorMode) + UpdateToolBarVariant(0); + else UpdateToolBarVariant(1); + } + + private void ToolbarButton_MouseDown(object sender, MouseButtonEventArgs e) { + if (_mouseDownButton != null) return; + var gd = sender as Grid; + var itemData = gd.Tag as FloatingBarItem; + _mouseDownButton = gd; + if (!itemData.Selected) { + var bgImg = gd.Children[1] as Image; + bgImg.Opacity = 1; + } + } + + private void ToolbarButton_MouseUp(object sender, MouseButtonEventArgs e) { + if (_mouseDownButton == null || _mouseDownButton != sender) return; + ToolbarButton_MouseLeave(sender, null); + + var gd = sender as Grid; + var itemData = gd.Tag as FloatingBarItem; + if (itemData.Type == FloatingBarItemType.StateButton) { + UpdateToolBarSelectedTool(itemData.ToolType); + OnToolSelectionChanged(itemData); + } + } + + [DllImport("USER32.DLL", SetLastError = true)] + public static extern int GetSystemMetrics(int nIndex); + + private void ToolbarButton_MouseLeave(object sender, MouseEventArgs e) { + if (_mouseDownButton == null || _mouseDownButton != sender) return; + var itemData = _mouseDownButton.Tag as FloatingBarItem; + if (!itemData.Selected) { + var bgImg = _mouseDownButton.Children[1] as Image; + bgImg.Opacity = 0; + } + _mouseDownButton = null; + } + + public Point prevPoint = new Point(0,0); + public Point lastPoint = new Point(0, 0); + public bool isInMovingMode = false; + public double winLeft = 0; + public double winTop = 0; + + private void HeadIconButton_MouseDown(object sender, MouseButtonEventArgs e) { + if (_isMouseDownHeadIcon) return; + _isMouseDownHeadIcon = true; + var gd = sender as Grid; + prevPoint = e.GetPosition(ToolBarV2Grid); + winLeft = Left; + winTop = Top; + Trace.WriteLine(prevPoint); + gd.CaptureMouse(); + gd.RenderTransform = new ScaleTransform(0.95, 0.95); + isInMovingMode = false; + } + + private void HeadIconButton_MouseMove(object sender, MouseEventArgs e) { + if (_isMouseDownHeadIcon == false) return; + var nowPt = e.GetPosition(ToolBarV2Grid); + lastPoint = nowPt; + var deltaX = nowPt.X - prevPoint.X; + var deltaY = nowPt.Y - prevPoint.Y; + if (Math.Abs(deltaY) > 16 || Math.Abs(deltaX) > 16) isInMovingMode = true; + if (isInMovingMode) { + ToolbarV2.RenderTransform = null; + HeadIconImage.RenderTransform = null; + var mp = System.Windows.Forms.Control.MousePosition; + Top = mp.Y * ScalingFactor - prevPoint.Y - 6; + Left = mp.X * ScalingFactor - prevPoint.X - 6; + } else { + ToolbarV2.RenderTransform = new TranslateTransform(deltaX / 3, deltaY / 3); + HeadIconImage.RenderTransform = new TranslateTransform(deltaX / 8, deltaY / 8); + } + } + + private void HeadIconButton_MouseUp(object sender, MouseButtonEventArgs e) { + if (_isMouseDownHeadIcon == false) return; + _isMouseDownHeadIcon = false; + var gd = sender as Grid; + gd.ReleaseMouseCapture(); + gd.RenderTransform = null; + ToolbarV2.RenderTransform = null; + HeadIconImage.RenderTransform = null; + isInMovingMode = false; + } + } +} diff --git a/InkCanvasForClass/Resources/Icons-png/icc-toolbar-v2.png b/InkCanvasForClass/Resources/Icons-png/icc-toolbar-v2.png new file mode 100644 index 0000000000000000000000000000000000000000..b64fa6e4952cba9a29ff220d00f2f67c019cfc73 GIT binary patch literal 10643 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 literal 0 HcmV?d00001