2024-05-03 17:52:05 +08:00
|
|
|
|
using iNKORE.UI.WPF.Modern.Controls;
|
|
|
|
|
using System;
|
2024-06-09 15:14:58 +08:00
|
|
|
|
using System.Collections.Generic;
|
2024-05-01 18:23:32 +08:00
|
|
|
|
using System.Windows;
|
|
|
|
|
using System.Windows.Controls;
|
|
|
|
|
using System.Windows.Ink;
|
|
|
|
|
using System.Windows.Input;
|
|
|
|
|
using System.Windows.Media;
|
2024-05-03 17:52:05 +08:00
|
|
|
|
using System.Windows.Media.Imaging;
|
2024-05-01 18:23:32 +08:00
|
|
|
|
using Point = System.Windows.Point;
|
|
|
|
|
|
|
|
|
|
namespace Ink_Canvas {
|
|
|
|
|
public partial class MainWindow : Window {
|
|
|
|
|
#region Floating Control
|
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
private object lastBorderMouseDownObject;
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
private void Border_MouseDown(object sender, MouseButtonEventArgs e) {
|
|
|
|
|
lastBorderMouseDownObject = sender;
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
private bool isStrokeSelectionCloneOn = false;
|
|
|
|
|
|
|
|
|
|
private void BorderStrokeSelectionClone_MouseUp(object sender, MouseButtonEventArgs e) {
|
2024-05-01 18:23:32 +08:00
|
|
|
|
if (lastBorderMouseDownObject != sender) return;
|
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
if (isStrokeSelectionCloneOn) {
|
2024-05-01 18:23:32 +08:00
|
|
|
|
BorderStrokeSelectionClone.Background = Brushes.Transparent;
|
|
|
|
|
|
|
|
|
|
isStrokeSelectionCloneOn = false;
|
2024-06-05 19:57:15 +08:00
|
|
|
|
}
|
2024-06-05 20:25:26 +08:00
|
|
|
|
else {
|
2024-05-01 18:23:32 +08:00
|
|
|
|
BorderStrokeSelectionClone.Background = new SolidColorBrush(StringToColor("#FF1ED760"));
|
|
|
|
|
|
|
|
|
|
isStrokeSelectionCloneOn = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void BorderStrokeSelectionCloneToNewBoard_MouseUp(object sender, MouseButtonEventArgs e) {
|
|
|
|
|
if (lastBorderMouseDownObject != sender) return;
|
|
|
|
|
|
|
|
|
|
var strokes = inkCanvas.GetSelectedStrokes();
|
|
|
|
|
inkCanvas.Select(new StrokeCollection());
|
|
|
|
|
strokes = strokes.Clone();
|
|
|
|
|
BtnWhiteBoardAdd_Click(null, null);
|
|
|
|
|
inkCanvas.Strokes.Add(strokes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void BorderStrokeSelectionDelete_MouseUp(object sender, MouseButtonEventArgs e) {
|
|
|
|
|
if (lastBorderMouseDownObject != sender) return;
|
|
|
|
|
SymbolIconDelete_MouseUp(sender, e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void GridPenWidthDecrease_MouseUp(object sender, MouseButtonEventArgs e) {
|
|
|
|
|
if (lastBorderMouseDownObject != sender) return;
|
|
|
|
|
ChangeStrokeThickness(0.8);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void GridPenWidthIncrease_MouseUp(object sender, MouseButtonEventArgs e) {
|
|
|
|
|
if (lastBorderMouseDownObject != sender) return;
|
|
|
|
|
ChangeStrokeThickness(1.25);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ChangeStrokeThickness(double multipler) {
|
2024-06-05 20:25:26 +08:00
|
|
|
|
foreach (var stroke in inkCanvas.GetSelectedStrokes()) {
|
2024-05-01 18:23:32 +08:00
|
|
|
|
var newWidth = stroke.DrawingAttributes.Width * multipler;
|
|
|
|
|
var newHeight = stroke.DrawingAttributes.Height * multipler;
|
2024-06-05 20:25:26 +08:00
|
|
|
|
if (!(newWidth >= DrawingAttributes.MinWidth) || !(newWidth <= DrawingAttributes.MaxWidth)
|
|
|
|
|
|| !(newHeight >= DrawingAttributes.MinHeight) ||
|
|
|
|
|
!(newHeight <= DrawingAttributes.MaxHeight)) continue;
|
|
|
|
|
stroke.DrawingAttributes.Width = newWidth;
|
|
|
|
|
stroke.DrawingAttributes.Height = newHeight;
|
2024-05-01 18:23:32 +08:00
|
|
|
|
}
|
2024-06-09 15:14:58 +08:00
|
|
|
|
if (DrawingAttributesHistory.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
timeMachine.CommitStrokeDrawingAttributesHistory(DrawingAttributesHistory);
|
|
|
|
|
DrawingAttributesHistory = new Dictionary<Stroke, Tuple<DrawingAttributes, DrawingAttributes>>();
|
|
|
|
|
foreach (var item in DrawingAttributesHistoryFlag)
|
|
|
|
|
{
|
|
|
|
|
item.Value.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-01 18:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void GridPenWidthRestore_MouseUp(object sender, MouseButtonEventArgs e) {
|
|
|
|
|
if (lastBorderMouseDownObject != sender) return;
|
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
foreach (var stroke in inkCanvas.GetSelectedStrokes()) {
|
2024-05-01 18:23:32 +08:00
|
|
|
|
stroke.DrawingAttributes.Width = inkCanvas.DefaultDrawingAttributes.Width;
|
|
|
|
|
stroke.DrawingAttributes.Height = inkCanvas.DefaultDrawingAttributes.Height;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ImageFlipHorizontal_MouseUp(object sender, MouseButtonEventArgs e) {
|
|
|
|
|
if (lastBorderMouseDownObject != sender) return;
|
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var m = new Matrix();
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
// Find center of element and then transform to get current location of center
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var fe = e.Source as FrameworkElement;
|
|
|
|
|
var center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
|
2024-05-01 18:23:32 +08:00
|
|
|
|
center = new Point(inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Width / 2,
|
|
|
|
|
inkCanvas.GetSelectionBounds().Top + inkCanvas.GetSelectionBounds().Height / 2);
|
2024-06-05 20:25:26 +08:00
|
|
|
|
center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
// Update matrix to reflect translation/rotation
|
2024-06-05 20:25:26 +08:00
|
|
|
|
m.ScaleAt(-1, 1, center.X, center.Y); // 缩放
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var targetStrokes = inkCanvas.GetSelectedStrokes();
|
|
|
|
|
foreach (var stroke in targetStrokes) stroke.Transform(m, false);
|
2024-06-09 15:14:58 +08:00
|
|
|
|
|
|
|
|
|
if (DrawingAttributesHistory.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
//var collecion = new StrokeCollection();
|
|
|
|
|
//foreach (var item in DrawingAttributesHistory)
|
|
|
|
|
//{
|
|
|
|
|
// collecion.Add(item.Key);
|
|
|
|
|
//}
|
|
|
|
|
timeMachine.CommitStrokeDrawingAttributesHistory(DrawingAttributesHistory);
|
|
|
|
|
DrawingAttributesHistory = new Dictionary<Stroke, Tuple<DrawingAttributes, DrawingAttributes>>();
|
|
|
|
|
foreach (var item in DrawingAttributesHistoryFlag)
|
|
|
|
|
{
|
|
|
|
|
item.Value.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
//updateBorderStrokeSelectionControlLocation();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ImageFlipVertical_MouseUp(object sender, MouseButtonEventArgs e) {
|
|
|
|
|
if (lastBorderMouseDownObject != sender) return;
|
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var m = new Matrix();
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
// Find center of element and then transform to get current location of center
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var fe = e.Source as FrameworkElement;
|
|
|
|
|
var center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
|
2024-05-01 18:23:32 +08:00
|
|
|
|
center = new Point(inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Width / 2,
|
|
|
|
|
inkCanvas.GetSelectionBounds().Top + inkCanvas.GetSelectionBounds().Height / 2);
|
2024-06-05 20:25:26 +08:00
|
|
|
|
center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
// Update matrix to reflect translation/rotation
|
2024-06-05 20:25:26 +08:00
|
|
|
|
m.ScaleAt(1, -1, center.X, center.Y); // 缩放
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var targetStrokes = inkCanvas.GetSelectedStrokes();
|
|
|
|
|
foreach (var stroke in targetStrokes) stroke.Transform(m, false);
|
2024-06-09 15:14:58 +08:00
|
|
|
|
|
|
|
|
|
if (DrawingAttributesHistory.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
timeMachine.CommitStrokeDrawingAttributesHistory(DrawingAttributesHistory);
|
|
|
|
|
DrawingAttributesHistory = new Dictionary<Stroke, Tuple<DrawingAttributes, DrawingAttributes>>();
|
|
|
|
|
foreach (var item in DrawingAttributesHistoryFlag)
|
|
|
|
|
{
|
|
|
|
|
item.Value.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-01 18:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ImageRotate45_MouseUp(object sender, MouseButtonEventArgs e) {
|
|
|
|
|
if (lastBorderMouseDownObject != sender) return;
|
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var m = new Matrix();
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
// Find center of element and then transform to get current location of center
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var fe = e.Source as FrameworkElement;
|
|
|
|
|
var center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
|
2024-05-01 18:23:32 +08:00
|
|
|
|
center = new Point(inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Width / 2,
|
|
|
|
|
inkCanvas.GetSelectionBounds().Top + inkCanvas.GetSelectionBounds().Height / 2);
|
2024-06-05 20:25:26 +08:00
|
|
|
|
center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
// Update matrix to reflect translation/rotation
|
2024-06-05 20:25:26 +08:00
|
|
|
|
m.RotateAt(45, center.X, center.Y); // 旋转
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var targetStrokes = inkCanvas.GetSelectedStrokes();
|
|
|
|
|
foreach (var stroke in targetStrokes) stroke.Transform(m, false);
|
2024-06-09 15:14:58 +08:00
|
|
|
|
|
|
|
|
|
if (DrawingAttributesHistory.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
timeMachine.CommitStrokeDrawingAttributesHistory(DrawingAttributesHistory);
|
|
|
|
|
DrawingAttributesHistory = new Dictionary<Stroke, Tuple<DrawingAttributes, DrawingAttributes>>();
|
|
|
|
|
foreach (var item in DrawingAttributesHistoryFlag)
|
|
|
|
|
{
|
|
|
|
|
item.Value.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-01 18:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ImageRotate90_MouseUp(object sender, MouseButtonEventArgs e) {
|
|
|
|
|
if (lastBorderMouseDownObject != sender) return;
|
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var m = new Matrix();
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
// Find center of element and then transform to get current location of center
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var fe = e.Source as FrameworkElement;
|
|
|
|
|
var center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
|
2024-05-01 18:23:32 +08:00
|
|
|
|
center = new Point(inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Width / 2,
|
|
|
|
|
inkCanvas.GetSelectionBounds().Top + inkCanvas.GetSelectionBounds().Height / 2);
|
2024-06-05 20:25:26 +08:00
|
|
|
|
center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
// Update matrix to reflect translation/rotation
|
2024-06-05 20:25:26 +08:00
|
|
|
|
m.RotateAt(90, center.X, center.Y); // 旋转
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var targetStrokes = inkCanvas.GetSelectedStrokes();
|
|
|
|
|
foreach (var stroke in targetStrokes) stroke.Transform(m, false);
|
2024-06-09 15:14:58 +08:00
|
|
|
|
|
|
|
|
|
if (DrawingAttributesHistory.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
var collecion = new StrokeCollection();
|
|
|
|
|
foreach (var item in DrawingAttributesHistory)
|
|
|
|
|
{
|
|
|
|
|
collecion.Add(item.Key);
|
|
|
|
|
}
|
|
|
|
|
timeMachine.CommitStrokeDrawingAttributesHistory(DrawingAttributesHistory);
|
|
|
|
|
DrawingAttributesHistory = new Dictionary<Stroke, Tuple<DrawingAttributes, DrawingAttributes>>();
|
|
|
|
|
foreach (var item in DrawingAttributesHistoryFlag)
|
|
|
|
|
{
|
|
|
|
|
item.Value.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-01 18:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
private bool isGridInkCanvasSelectionCoverMouseDown = false;
|
|
|
|
|
private StrokeCollection StrokesSelectionClone = new StrokeCollection();
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
private void GridInkCanvasSelectionCover_MouseDown(object sender, MouseButtonEventArgs e) {
|
|
|
|
|
isGridInkCanvasSelectionCoverMouseDown = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void GridInkCanvasSelectionCover_MouseUp(object sender, MouseButtonEventArgs e) {
|
2024-06-05 20:25:26 +08:00
|
|
|
|
if (!isGridInkCanvasSelectionCoverMouseDown) return;
|
|
|
|
|
isGridInkCanvasSelectionCoverMouseDown = false;
|
|
|
|
|
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
|
2024-05-01 18:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void BtnSelect_Click(object sender, RoutedEventArgs e) {
|
|
|
|
|
forceEraser = true;
|
|
|
|
|
drawingShapeMode = 0;
|
|
|
|
|
inkCanvas.IsManipulationEnabled = false;
|
|
|
|
|
if (inkCanvas.EditingMode == InkCanvasEditingMode.Select) {
|
|
|
|
|
if (inkCanvas.GetSelectedStrokes().Count == inkCanvas.Strokes.Count) {
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
|
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.Select;
|
2024-06-05 20:25:26 +08:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
var selectedStrokes = new StrokeCollection();
|
|
|
|
|
foreach (var stroke in inkCanvas.Strokes)
|
|
|
|
|
if (stroke.GetBounds().Width > 0 && stroke.GetBounds().Height > 0)
|
2024-05-01 18:23:32 +08:00
|
|
|
|
selectedStrokes.Add(stroke);
|
|
|
|
|
inkCanvas.Select(selectedStrokes);
|
|
|
|
|
}
|
2024-06-05 20:25:26 +08:00
|
|
|
|
}
|
|
|
|
|
else {
|
2024-05-01 18:23:32 +08:00
|
|
|
|
inkCanvas.EditingMode = InkCanvasEditingMode.Select;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
private double BorderStrokeSelectionControlWidth = 490.0;
|
|
|
|
|
private double BorderStrokeSelectionControlHeight = 80.0;
|
|
|
|
|
private bool isProgramChangeStrokeSelection = false;
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
private void inkCanvas_SelectionChanged(object sender, EventArgs e) {
|
|
|
|
|
if (isProgramChangeStrokeSelection) return;
|
|
|
|
|
if (inkCanvas.GetSelectedStrokes().Count == 0) {
|
|
|
|
|
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
|
2024-06-05 20:25:26 +08:00
|
|
|
|
}
|
|
|
|
|
else {
|
2024-05-01 18:23:32 +08:00
|
|
|
|
GridInkCanvasSelectionCover.Visibility = Visibility.Visible;
|
|
|
|
|
BorderStrokeSelectionClone.Background = Brushes.Transparent;
|
|
|
|
|
isStrokeSelectionCloneOn = false;
|
|
|
|
|
updateBorderStrokeSelectionControlLocation();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void updateBorderStrokeSelectionControlLocation() {
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var borderLeft = (inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Right -
|
|
|
|
|
BorderStrokeSelectionControlWidth) / 2;
|
|
|
|
|
var borderTop = inkCanvas.GetSelectionBounds().Bottom + 1;
|
2024-05-01 18:23:32 +08:00
|
|
|
|
if (borderLeft < 0) borderLeft = 0;
|
|
|
|
|
if (borderTop < 0) borderTop = 0;
|
2024-06-05 20:25:26 +08:00
|
|
|
|
if (Width - borderLeft < BorderStrokeSelectionControlWidth || double.IsNaN(borderLeft))
|
|
|
|
|
borderLeft = Width - BorderStrokeSelectionControlWidth;
|
|
|
|
|
if (Height - borderTop < BorderStrokeSelectionControlHeight || double.IsNaN(borderTop))
|
|
|
|
|
borderTop = Height - BorderStrokeSelectionControlHeight;
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
if (borderTop > 60) borderTop -= 60;
|
|
|
|
|
BorderStrokeSelectionControl.Margin = new Thickness(borderLeft, borderTop, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void GridInkCanvasSelectionCover_ManipulationStarting(object sender, ManipulationStartingEventArgs e) {
|
|
|
|
|
e.Mode = ManipulationModes.All;
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-09 15:14:58 +08:00
|
|
|
|
private void GridInkCanvasSelectionCover_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) {
|
|
|
|
|
if (StrokeManipulationHistory?.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
timeMachine.CommitStrokeManipulationHistory(StrokeManipulationHistory);
|
|
|
|
|
foreach (var item in StrokeManipulationHistory)
|
|
|
|
|
{
|
|
|
|
|
StrokeInitialHistory[item.Key] = item.Value.Item2;
|
|
|
|
|
}
|
|
|
|
|
StrokeManipulationHistory = null;
|
|
|
|
|
}
|
|
|
|
|
if (DrawingAttributesHistory.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
timeMachine.CommitStrokeDrawingAttributesHistory(DrawingAttributesHistory);
|
|
|
|
|
DrawingAttributesHistory = new Dictionary<Stroke, Tuple<DrawingAttributes, DrawingAttributes>>();
|
|
|
|
|
foreach (var item in DrawingAttributesHistoryFlag)
|
|
|
|
|
{
|
|
|
|
|
item.Value.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
private void GridInkCanvasSelectionCover_ManipulationDelta(object sender, ManipulationDeltaEventArgs e) {
|
|
|
|
|
try {
|
|
|
|
|
if (dec.Count >= 1) {
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var md = e.DeltaManipulation;
|
|
|
|
|
var trans = md.Translation; // 获得位移矢量
|
|
|
|
|
var rotate = md.Rotation; // 获得旋转角度
|
|
|
|
|
var scale = md.Scale; // 获得缩放倍数
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var m = new Matrix();
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
// Find center of element and then transform to get current location of center
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var fe = e.Source as FrameworkElement;
|
|
|
|
|
var center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
|
2024-05-01 18:23:32 +08:00
|
|
|
|
center = new Point(inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Width / 2,
|
|
|
|
|
inkCanvas.GetSelectionBounds().Top + inkCanvas.GetSelectionBounds().Height / 2);
|
2024-06-05 20:25:26 +08:00
|
|
|
|
center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
// Update matrix to reflect translation/rotation
|
2024-06-05 20:25:26 +08:00
|
|
|
|
m.Translate(trans.X, trans.Y); // 移动
|
|
|
|
|
m.ScaleAt(scale.X, scale.Y, center.X, center.Y); // 缩放
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var strokes = inkCanvas.GetSelectedStrokes();
|
|
|
|
|
if (StrokesSelectionClone.Count != 0)
|
2024-05-01 18:23:32 +08:00
|
|
|
|
strokes = StrokesSelectionClone;
|
2024-06-05 20:25:26 +08:00
|
|
|
|
else if (Settings.Gesture.IsEnableTwoFingerRotationOnSelection)
|
|
|
|
|
m.RotateAt(rotate, center.X, center.Y); // 旋转
|
|
|
|
|
foreach (var stroke in strokes) {
|
2024-05-01 18:23:32 +08:00
|
|
|
|
stroke.Transform(m, false);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
stroke.DrawingAttributes.Width *= md.Scale.X;
|
|
|
|
|
stroke.DrawingAttributes.Height *= md.Scale.Y;
|
2024-06-05 20:25:26 +08:00
|
|
|
|
}
|
|
|
|
|
catch { }
|
2024-05-01 18:23:32 +08:00
|
|
|
|
}
|
2024-06-05 20:25:26 +08:00
|
|
|
|
|
2024-05-01 18:23:32 +08:00
|
|
|
|
updateBorderStrokeSelectionControlLocation();
|
|
|
|
|
}
|
2024-06-05 20:25:26 +08:00
|
|
|
|
}
|
|
|
|
|
catch { }
|
2024-05-01 18:23:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
private void GridInkCanvasSelectionCover_TouchDown(object sender, TouchEventArgs e) { }
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
2024-06-05 20:25:26 +08:00
|
|
|
|
private void GridInkCanvasSelectionCover_TouchUp(object sender, TouchEventArgs e) { }
|
|
|
|
|
|
|
|
|
|
private Point lastTouchPointOnGridInkCanvasCover = new Point(0, 0);
|
2024-05-01 18:23:32 +08:00
|
|
|
|
|
|
|
|
|
private void GridInkCanvasSelectionCover_PreviewTouchDown(object sender, TouchEventArgs e) {
|
|
|
|
|
dec.Add(e.TouchDevice.Id);
|
|
|
|
|
//设备1个的时候,记录中心点
|
|
|
|
|
if (dec.Count == 1) {
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var touchPoint = e.GetTouchPoint(null);
|
2024-05-01 18:23:32 +08:00
|
|
|
|
centerPoint = touchPoint.Position;
|
|
|
|
|
lastTouchPointOnGridInkCanvasCover = touchPoint.Position;
|
|
|
|
|
|
|
|
|
|
if (isStrokeSelectionCloneOn) {
|
2024-06-05 20:25:26 +08:00
|
|
|
|
var strokes = inkCanvas.GetSelectedStrokes();
|
2024-05-01 18:23:32 +08:00
|
|
|
|
isProgramChangeStrokeSelection = true;
|
|
|
|
|
inkCanvas.Select(new StrokeCollection());
|
|
|
|
|
StrokesSelectionClone = strokes.Clone();
|
|
|
|
|
inkCanvas.Select(strokes);
|
|
|
|
|
isProgramChangeStrokeSelection = false;
|
|
|
|
|
inkCanvas.Strokes.Add(StrokesSelectionClone);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void GridInkCanvasSelectionCover_PreviewTouchUp(object sender, TouchEventArgs e) {
|
|
|
|
|
dec.Remove(e.TouchDevice.Id);
|
|
|
|
|
if (dec.Count >= 1) return;
|
|
|
|
|
isProgramChangeStrokeSelection = false;
|
|
|
|
|
if (lastTouchPointOnGridInkCanvasCover == e.GetTouchPoint(null).Position) {
|
2024-06-05 20:25:26 +08:00
|
|
|
|
if (!(lastTouchPointOnGridInkCanvasCover.X < inkCanvas.GetSelectionBounds().Left) &&
|
|
|
|
|
!(lastTouchPointOnGridInkCanvasCover.Y < inkCanvas.GetSelectionBounds().Top) &&
|
|
|
|
|
!(lastTouchPointOnGridInkCanvasCover.X > inkCanvas.GetSelectionBounds().Right) &&
|
|
|
|
|
!(lastTouchPointOnGridInkCanvasCover.Y > inkCanvas.GetSelectionBounds().Bottom)) return;
|
|
|
|
|
inkCanvas.Select(new StrokeCollection());
|
|
|
|
|
StrokesSelectionClone = new StrokeCollection();
|
|
|
|
|
}
|
|
|
|
|
else if (inkCanvas.GetSelectedStrokes().Count == 0) {
|
2024-05-01 18:23:32 +08:00
|
|
|
|
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
|
|
|
|
|
StrokesSelectionClone = new StrokeCollection();
|
2024-06-05 20:25:26 +08:00
|
|
|
|
}
|
|
|
|
|
else {
|
2024-05-01 18:23:32 +08:00
|
|
|
|
GridInkCanvasSelectionCover.Visibility = Visibility.Visible;
|
|
|
|
|
StrokesSelectionClone = new StrokeCollection();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-06-05 20:25:26 +08:00
|
|
|
|
}
|