diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index 3866a24..20753e3 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -103,7 +103,7 @@ + HorizontalAlignment="Left" Margin="300,150,0,350" Visibility="Visible"> - @@ -1521,6 +1521,34 @@ HorizontalAlignment="Center" FontSize="12" /> + + + + + + + + + + + + + + + + + + + + + + + + - + Geometry="F0 M24,24z M0,0z M7.39778,13.723L10.7693,13.723 10.7693,10.3514 13.2307,10.3514 13.2307,13.723 16.6022,13.723 16.6022,16.1843 13.2307,16.1843 13.2307,19.5559 10.7693,19.5559 10.7693,16.1843 7.39778,16.1843 7.39778,13.723z M3.1391,1.17001L3.1391,22.83 20.8609,22.83 20.8609,6.66948 15.3614,1.17002 3.1391,1.17001z M12.9846,3.13911L5.10819,3.1391 5.10819,20.8609 18.8918,20.8609 18.8918,9.04638 12.9846,9.04638 12.9846,3.13911z M18.484,7.07729L14.9536,3.54692 14.9536,7.07729 18.484,7.07729z" /> @@ -3167,9 +3193,7 @@ - + Geometry="F0 M24,24z M0,0z M7.39778,13.723L10.7693,13.723 10.7693,10.3514 13.2307,10.3514 13.2307,13.723 16.6022,13.723 16.6022,16.1843 13.2307,16.1843 13.2307,19.5559 10.7693,19.5559 10.7693,16.1843 7.39778,16.1843 7.39778,13.723z M3.1391,1.17001L3.1391,22.83 20.8609,22.83 20.8609,6.66948 15.3614,1.17002 3.1391,1.17001z M12.9846,3.13911L5.10819,3.1391 5.10819,20.8609 18.8918,20.8609 18.8918,9.04638 12.9846,9.04638 12.9846,3.13911z M18.484,7.07729L14.9536,3.54692 14.9536,7.07729 18.484,7.07729z" /> diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs index c47e85f..607791b 100644 --- a/Ink Canvas/MainWindow.xaml.cs +++ b/Ink Canvas/MainWindow.xaml.cs @@ -177,6 +177,8 @@ namespace Ink_Canvas { FullScreenHelper.MarkFullscreenWindowTaskbarList(new WindowInteropHelper(this).Handle, true); isLoaded = true; + + BlackBoardLeftSidePageListView.ItemsSource = blackBoardLeftSidePageListViewObservableCollection; } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { diff --git a/Ink Canvas/MainWindow_cs/MW_BoardControls.cs b/Ink Canvas/MainWindow_cs/MW_BoardControls.cs index 4778385..0e31e36 100644 --- a/Ink Canvas/MainWindow_cs/MW_BoardControls.cs +++ b/Ink Canvas/MainWindow_cs/MW_BoardControls.cs @@ -1,8 +1,14 @@ using Ink_Canvas.Helpers; using System; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.Linq; using System.Windows; using System.Windows.Ink; +using System.Windows.Media.Animation; +using System.Windows.Media; using System.Windows.Media.Imaging; +using System.Xml.Linq; namespace Ink_Canvas { public partial class MainWindow : Window { @@ -51,6 +57,55 @@ namespace Ink_Canvas { } } + private void BtnWhiteBoardPageIndex_Click(object sender, EventArgs e) { + if (BoardBorderLeftPageListView.Visibility == Visibility.Visible) { + AnimationsHelper.HideWithSlideAndFade(BoardBorderLeftPageListView); + } else { + RefreshBlackBoardLeftSidePageListView(); + + try + { + var sb = new Storyboard(); + + // 渐变动画 + var fadeInAnimation = new DoubleAnimation + { + From = 0.5, + To = 1, + Duration = TimeSpan.FromSeconds(0.15) + }; + fadeInAnimation.EasingFunction = new CubicEase(); + + Storyboard.SetTargetProperty(fadeInAnimation, new PropertyPath(UIElement.OpacityProperty)); + + // 滑动动画 + var slideAnimation = new DoubleAnimation + { + From = BoardBorderLeftPageListView.RenderTransform.Value.OffsetY + 10, // 滑动距离 + To = 0, + Duration = TimeSpan.FromSeconds(0.15) + }; + Storyboard.SetTargetProperty(slideAnimation, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.Y)")); + + slideAnimation.EasingFunction = new CubicEase(); + + sb.Children.Add(fadeInAnimation); + sb.Children.Add(slideAnimation); + + sb.Completed += (_,__) => { + BlackBoardLeftSidePageListView.ScrollIntoView(BlackBoardLeftSidePageListView.SelectedItem); + }; + + BoardBorderLeftPageListView.Visibility = Visibility.Visible; + BoardBorderLeftPageListView.RenderTransform = new TranslateTransform(); + + sb.Begin((FrameworkElement)BoardBorderLeftPageListView); + } + catch { } + } + + } + private void BtnWhiteBoardSwitchPrevious_Click(object sender, EventArgs e) { if (CurrentWhiteboardIndex <= 1) return; diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index af35978..3d94f67 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -207,6 +207,7 @@ namespace Ink_Canvas { BoardEraserSizePanel.Visibility = Visibility.Collapsed; EraserSizePanel.Visibility = Visibility.Collapsed; BorderSettings.Visibility = Visibility.Collapsed; + BoardBorderLeftPageListView.Visibility = Visibility.Collapsed; } /// @@ -276,6 +277,7 @@ namespace Ink_Canvas { AnimationsHelper.HideWithSlideAndFade(BoardEraserSizePanel); AnimationsHelper.HideWithSlideAndFade(EraserSizePanel); AnimationsHelper.HideWithSlideAndFade(BorderDrawShape); + AnimationsHelper.HideWithSlideAndFade(BoardBorderLeftPageListView); if (BorderSettings.Visibility == Visibility.Visible) { BorderSettingsMask.IsHitTestVisible = false; diff --git a/Ink Canvas/MainWindow_cs/MW_PageListView.cs b/Ink Canvas/MainWindow_cs/MW_PageListView.cs new file mode 100644 index 0000000..ea2b5e2 --- /dev/null +++ b/Ink Canvas/MainWindow_cs/MW_PageListView.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Ink; +using System.Windows.Input; + +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { + private class PageListViewItem + { + public int Index { get; set; } + public StrokeCollection Strokes { get; set; } + } + + ObservableCollection blackBoardLeftSidePageListViewObservableCollection = new ObservableCollection(); + + /// + /// 刷新白板的缩略图页面列表。 + /// + private void RefreshBlackBoardLeftSidePageListView() + { + if (blackBoardLeftSidePageListViewObservableCollection.Count == WhiteboardTotalCount) { + foreach (int index in Enumerable.Range(1, WhiteboardTotalCount)) + { + var pitem = new PageListViewItem() + { + Index = index, + Strokes = ApplyHistoriesToNewStrokeCollection(TimeMachineHistories[index]), + }; + blackBoardLeftSidePageListViewObservableCollection[index-1] = pitem; + } + } else { + blackBoardLeftSidePageListViewObservableCollection.Clear(); + foreach (int index in Enumerable.Range(1, WhiteboardTotalCount)) + { + var pitem = new PageListViewItem() + { + Index = index, + Strokes = ApplyHistoriesToNewStrokeCollection(TimeMachineHistories[index]), + }; + blackBoardLeftSidePageListViewObservableCollection.Add(pitem); + } + } + + var _pitem = new PageListViewItem() + { + Index = CurrentWhiteboardIndex, + Strokes = inkCanvas.Strokes, + }; + blackBoardLeftSidePageListViewObservableCollection[CurrentWhiteboardIndex - 1] = _pitem; + + BlackBoardLeftSidePageListView.SelectedIndex = CurrentWhiteboardIndex -1; + } + + private void BlackBoardLeftSidePageListView_OnMouseUp(object sender, MouseButtonEventArgs e) { + var item = BlackBoardLeftSidePageListView.SelectedItem; + var index = BlackBoardLeftSidePageListView.SelectedIndex; + if (item != null) + { + SaveStrokes(); + ClearStrokes(true); + CurrentWhiteboardIndex= index+1; + RestoreStrokes(); + UpdateIndexInfoDisplay(); + BlackBoardLeftSidePageListView.SelectedIndex = index; + } + } + } +} diff --git a/Ink Canvas/MainWindow_cs/MW_TimeMachine.cs b/Ink Canvas/MainWindow_cs/MW_TimeMachine.cs index 1d0a5c1..70ac2da 100644 --- a/Ink Canvas/MainWindow_cs/MW_TimeMachine.cs +++ b/Ink Canvas/MainWindow_cs/MW_TimeMachine.cs @@ -25,10 +25,14 @@ namespace Ink_Canvas { private StrokeCollection AddedStroke; private StrokeCollection CuboidStrokeCollection; private Dictionary> StrokeManipulationHistory; - private Dictionary StrokeInitialHistory = new Dictionary(); - private Dictionary> DrawingAttributesHistory = new Dictionary>(); - private Dictionary> DrawingAttributesHistoryFlag = new Dictionary>() - { + + private Dictionary StrokeInitialHistory = + new Dictionary(); + + private Dictionary> DrawingAttributesHistory = + new Dictionary>(); + + private Dictionary> DrawingAttributesHistoryFlag = new Dictionary>() { { DrawingAttributeIds.Color, new List() }, { DrawingAttributeIds.DrawingFlags, new List() }, { DrawingAttributeIds.IsHighlighter, new List() }, @@ -37,79 +41,68 @@ namespace Ink_Canvas { { DrawingAttributeIds.StylusTipTransform, new List() }, { DrawingAttributeIds.StylusWidth, new List() } }; + private TimeMachine timeMachine = new TimeMachine(); - private void ApplyHistoryToCanvas(TimeMachineHistory item) { + private void ApplyHistoryToCanvas(TimeMachineHistory item, InkCanvas applyCanvas = null) { _currentCommitType = CommitReason.CodeInput; + var canvas = inkCanvas; + if (applyCanvas != null && applyCanvas is InkCanvas) { + canvas = applyCanvas; + } + if (item.CommitType == TimeMachineHistoryType.UserInput) { if (!item.StrokeHasBeenCleared) { foreach (var strokes in item.CurrentStroke) - if (!inkCanvas.Strokes.Contains(strokes)) - inkCanvas.Strokes.Add(strokes); - } - else { + if (!canvas.Strokes.Contains(strokes)) + canvas.Strokes.Add(strokes); + } else { foreach (var strokes in item.CurrentStroke) - if (inkCanvas.Strokes.Contains(strokes)) - inkCanvas.Strokes.Remove(strokes); + if (canvas.Strokes.Contains(strokes)) + canvas.Strokes.Remove(strokes); } - } - else if (item.CommitType == TimeMachineHistoryType.ShapeRecognition) { + } else if (item.CommitType == TimeMachineHistoryType.ShapeRecognition) { if (item.StrokeHasBeenCleared) { foreach (var strokes in item.CurrentStroke) - if (inkCanvas.Strokes.Contains(strokes)) - inkCanvas.Strokes.Remove(strokes); + if (canvas.Strokes.Contains(strokes)) + canvas.Strokes.Remove(strokes); foreach (var strokes in item.ReplacedStroke) - if (!inkCanvas.Strokes.Contains(strokes)) - inkCanvas.Strokes.Add(strokes); - } - else { + if (!canvas.Strokes.Contains(strokes)) + canvas.Strokes.Add(strokes); + } else { foreach (var strokes in item.CurrentStroke) - if (!inkCanvas.Strokes.Contains(strokes)) - inkCanvas.Strokes.Add(strokes); + if (!canvas.Strokes.Contains(strokes)) + canvas.Strokes.Add(strokes); foreach (var strokes in item.ReplacedStroke) - if (inkCanvas.Strokes.Contains(strokes)) - inkCanvas.Strokes.Remove(strokes); + if (canvas.Strokes.Contains(strokes)) + canvas.Strokes.Remove(strokes); } - } - else if (item.CommitType == TimeMachineHistoryType.Manipulation) { + } else if (item.CommitType == TimeMachineHistoryType.Manipulation) { if (!item.StrokeHasBeenCleared) { foreach (var currentStroke in item.StylusPointDictionary) { - if (inkCanvas.Strokes.Contains(currentStroke.Key)) { + if (canvas.Strokes.Contains(currentStroke.Key)) { currentStroke.Key.StylusPoints = currentStroke.Value.Item2; } } - } - else - { - foreach (var currentStroke in item.StylusPointDictionary) - { - if (inkCanvas.Strokes.Contains(currentStroke.Key)) - { + } else { + foreach (var currentStroke in item.StylusPointDictionary) { + if (canvas.Strokes.Contains(currentStroke.Key)) { currentStroke.Key.StylusPoints = currentStroke.Value.Item1; } } } - } - else if (item.CommitType == TimeMachineHistoryType.DrawingAttributes) - { - if (!item.StrokeHasBeenCleared) - { - foreach (var currentStroke in item.DrawingAttributes) - { - if (inkCanvas.Strokes.Contains(currentStroke.Key)) - { + } else if (item.CommitType == TimeMachineHistoryType.DrawingAttributes) { + if (!item.StrokeHasBeenCleared) { + foreach (var currentStroke in item.DrawingAttributes) { + if (canvas.Strokes.Contains(currentStroke.Key)) { currentStroke.Key.DrawingAttributes = currentStroke.Value.Item2; } } - } - else - { - foreach (var currentStroke in item.DrawingAttributes) - { - if (inkCanvas.Strokes.Contains(currentStroke.Key)) - { + } else { + foreach (var currentStroke in item.DrawingAttributes) { + if (canvas.Strokes.Contains(currentStroke.Key)) { currentStroke.Key.DrawingAttributes = currentStroke.Value.Item1; } } @@ -118,30 +111,45 @@ namespace Ink_Canvas { if (!item.StrokeHasBeenCleared) { if (item.CurrentStroke != null) foreach (var currentStroke in item.CurrentStroke) - if (!inkCanvas.Strokes.Contains(currentStroke)) - inkCanvas.Strokes.Add(currentStroke); + if (!canvas.Strokes.Contains(currentStroke)) + canvas.Strokes.Add(currentStroke); if (item.ReplacedStroke != null) foreach (var replacedStroke in item.ReplacedStroke) - if (inkCanvas.Strokes.Contains(replacedStroke)) - inkCanvas.Strokes.Remove(replacedStroke); - } - else { + if (canvas.Strokes.Contains(replacedStroke)) + canvas.Strokes.Remove(replacedStroke); + } else { if (item.ReplacedStroke != null) foreach (var replacedStroke in item.ReplacedStroke) - if (!inkCanvas.Strokes.Contains(replacedStroke)) - inkCanvas.Strokes.Add(replacedStroke); + if (!canvas.Strokes.Contains(replacedStroke)) + canvas.Strokes.Add(replacedStroke); if (item.CurrentStroke != null) foreach (var currentStroke in item.CurrentStroke) - if (inkCanvas.Strokes.Contains(currentStroke)) - inkCanvas.Strokes.Remove(currentStroke); + if (canvas.Strokes.Contains(currentStroke)) + canvas.Strokes.Remove(currentStroke); } } _currentCommitType = CommitReason.UserInput; } + private StrokeCollection ApplyHistoriesToNewStrokeCollection(TimeMachineHistory[] items) { + InkCanvas fakeInkCanv = new InkCanvas() { + Width = inkCanvas.ActualWidth, + Height = inkCanvas.ActualHeight, + EditingMode = InkCanvasEditingMode.None, + }; + + if (items != null && items.Length > 0) { + foreach (var timeMachineHistory in items) { + ApplyHistoryToCanvas(timeMachineHistory, fakeInkCanv); + } + } + + return fakeInkCanv.Strokes; + } + private void TimeMachine_OnUndoStateChanged(bool status) { var result = status ? Visibility.Visible : Visibility.Collapsed; BtnUndo.Visibility = result; @@ -160,15 +168,14 @@ namespace Ink_Canvas { HideSubPanels(); // 书写时自动隐藏二级菜单 } - foreach (var stroke in e?.Removed) - { + foreach (var stroke in e?.Removed) { stroke.StylusPointsChanged -= Stroke_StylusPointsChanged; stroke.StylusPointsReplaced -= Stroke_StylusPointsReplaced; stroke.DrawingAttributesChanged -= Stroke_DrawingAttributesChanged; StrokeInitialHistory.Remove(stroke); } - foreach (var stroke in e?.Added) - { + + foreach (var stroke in e?.Added) { stroke.StylusPointsChanged += Stroke_StylusPointsChanged; stroke.StylusPointsReplaced += Stroke_StylusPointsReplaced; stroke.DrawingAttributesChanged += Stroke_DrawingAttributesChanged; @@ -190,8 +197,7 @@ namespace Ink_Canvas { timeMachine.CommitStrokeShapeHistory(ReplacedStroke, e.Added); ReplacedStroke = null; return; - } - else { + } else { timeMachine.CommitStrokeUserInputHistory(e.Added); return; } @@ -201,80 +207,78 @@ namespace Ink_Canvas { if (_currentCommitType == CommitReason.ShapeRecognition) { ReplacedStroke = e.Removed; return; - } - else if (!IsEraseByPoint || _currentCommitType == CommitReason.ClearingCanvas) { + } else if (!IsEraseByPoint || _currentCommitType == CommitReason.ClearingCanvas) { timeMachine.CommitStrokeEraseHistory(e.Removed); return; } } } - private void Stroke_DrawingAttributesChanged(object sender, PropertyDataChangedEventArgs e) - { + private void Stroke_DrawingAttributesChanged(object sender, PropertyDataChangedEventArgs e) { var key = sender as Stroke; var currentValue = key.DrawingAttributes.Clone(); DrawingAttributesHistory.TryGetValue(key, out var previousTuple); var previousValue = previousTuple?.Item1 ?? currentValue.Clone(); var needUpdateValue = !DrawingAttributesHistoryFlag[e.PropertyGuid].Contains(key); - if (needUpdateValue) - { + if (needUpdateValue) { DrawingAttributesHistoryFlag[e.PropertyGuid].Add(key); Debug.Write(e.PreviousValue.ToString()); } - if (e.PropertyGuid == DrawingAttributeIds.Color && needUpdateValue) - { + + if (e.PropertyGuid == DrawingAttributeIds.Color && needUpdateValue) { previousValue.Color = (Color)e.PreviousValue; } - if (e.PropertyGuid == DrawingAttributeIds.IsHighlighter && needUpdateValue) - { + + if (e.PropertyGuid == DrawingAttributeIds.IsHighlighter && needUpdateValue) { previousValue.IsHighlighter = (bool)e.PreviousValue; } - if (e.PropertyGuid == DrawingAttributeIds.StylusHeight && needUpdateValue) - { + + if (e.PropertyGuid == DrawingAttributeIds.StylusHeight && needUpdateValue) { previousValue.Height = (double)e.PreviousValue; } - if (e.PropertyGuid == DrawingAttributeIds.StylusWidth && needUpdateValue) - { + + if (e.PropertyGuid == DrawingAttributeIds.StylusWidth && needUpdateValue) { previousValue.Width = (double)e.PreviousValue; } - if (e.PropertyGuid == DrawingAttributeIds.StylusTip && needUpdateValue) - { + + if (e.PropertyGuid == DrawingAttributeIds.StylusTip && needUpdateValue) { previousValue.StylusTip = (StylusTip)e.PreviousValue; } - if (e.PropertyGuid == DrawingAttributeIds.StylusTipTransform && needUpdateValue) - { + + if (e.PropertyGuid == DrawingAttributeIds.StylusTipTransform && needUpdateValue) { previousValue.StylusTipTransform = (Matrix)e.PreviousValue; } - if (e.PropertyGuid == DrawingAttributeIds.DrawingFlags && needUpdateValue) - { + + if (e.PropertyGuid == DrawingAttributeIds.DrawingFlags && needUpdateValue) { previousValue.IgnorePressure = (bool)e.PreviousValue; } - DrawingAttributesHistory[key] = new Tuple(previousValue, currentValue); + + DrawingAttributesHistory[key] = + new Tuple(previousValue, currentValue); } - private void Stroke_StylusPointsReplaced(object sender, StylusPointsReplacedEventArgs e) - { + private void Stroke_StylusPointsReplaced(object sender, StylusPointsReplacedEventArgs e) { StrokeInitialHistory[sender as Stroke] = e.NewStylusPoints.Clone(); } - private void Stroke_StylusPointsChanged(object sender, EventArgs e) - { + private void Stroke_StylusPointsChanged(object sender, EventArgs e) { var selectedStrokes = inkCanvas.GetSelectedStrokes(); var count = selectedStrokes.Count; if (count == 0) count = inkCanvas.Strokes.Count; - if (StrokeManipulationHistory == null) - { - StrokeManipulationHistory = new Dictionary>(); + if (StrokeManipulationHistory == null) { + StrokeManipulationHistory = + new Dictionary>(); } + StrokeManipulationHistory[sender as Stroke] = - new Tuple(StrokeInitialHistory[sender as Stroke], (sender as Stroke).StylusPoints.Clone()); - if ((StrokeManipulationHistory.Count == count || sender == null) && dec.Count == 0) - { + new Tuple(StrokeInitialHistory[sender as Stroke], + (sender as Stroke).StylusPoints.Clone()); + if ((StrokeManipulationHistory.Count == count || sender == null) && dec.Count == 0) { timeMachine.CommitStrokeManipulationHistory(StrokeManipulationHistory); - foreach (var item in StrokeManipulationHistory) - { + foreach (var item in StrokeManipulationHistory) { StrokeInitialHistory[item.Key] = item.Value.Item2; } + StrokeManipulationHistory = null; } }