Bläddra i källkod

ComPDFKit.Demo(win) - 新增内容编辑Path对象属性面板

TangJinZhou 5 månader sedan
förälder
incheckning
7faf9611c3

+ 14 - 0
Demo/Examples/Compdfkit.Controls/Compdfkit.Controls.csproj

@@ -383,6 +383,12 @@
     <Compile Include="Edit\PDFImageEdit\PDFImageUI\CPDFImageRotateUI.xaml.cs">
       <DependentUpon>CPDFImageRotateUI.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Edit\PDFPathEdit\PDFPathEditControl\PDFPathEditControl.xaml.cs">
+      <DependentUpon>PDFPathEditControl.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Edit\PDFTextEdit\PDFTextEditUI\CPDFTextMarkupUI.xaml.cs">
+      <DependentUpon>CPDFTextMarkupUI.xaml</DependentUpon>
+    </Compile>
     <Compile Include="Edit\PDFTextEdit\PDFTextEditControl\PDFTextEditControl.xaml.cs">
       <DependentUpon>PDFTextEditControl.xaml</DependentUpon>
     </Compile>
@@ -1097,6 +1103,14 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="Edit\PDFPathEdit\PDFPathEditControl\PDFPathEditControl.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="Edit\PDFTextEdit\PDFTextEditUI\CPDFTextMarkupUI.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="Edit\PDFTextEdit\PDFTextEditControl\PDFTextEditControl.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>

+ 23 - 3
Demo/Examples/Compdfkit.Controls/Edit/ContentEditCOntrol/ContentEditControl.xaml.cs

@@ -748,14 +748,22 @@ namespace ComPDFKit.Controls.PDFControl
                     pdfContentEditControl.SetPDFTextEditData(editParams, true);
                     PropertyContainer.Child = pdfContentEditControl;
                 }
-                else if (editTextAreas.Count == 0 && editPathAreas.Count == 0)
+                else if (editAreas.Count == editImageAreas.Count)
                 {
-                    List<ImageEditParam> editParams = editAreas.
+                    List<ImageEditParam> editParams = editImageAreas.
                         Select(area => ParamConverter.CPDFDataConverterToPDFEitParam(PdfViewControl.PDFToolManager.GetDocument(), area, pageInts.FirstOrDefault())).
                         Cast<ImageEditParam>().ToList();
                     pdfContentEditControl.SetPDFImageEditData(editParams);
                     PropertyContainer.Child = pdfContentEditControl;
                 }
+                else if (editAreas.Count == editPathAreas.Count)
+                {
+                    List<PathEditParam> editParams = editPathAreas.
+                        Select(area => ParamConverter.CPDFDataConverterToPDFEitParam(PdfViewControl.PDFToolManager.GetDocument(), area, pageInts.FirstOrDefault())).
+                        Cast<PathEditParam>().ToList();
+                    pdfContentEditControl.SetPDFPathEditData(editParams);
+                    PropertyContainer.Child = pdfContentEditControl;
+                }
                 else
                 {
                     pdfContentEditControl.ClearContentControl();
@@ -794,7 +802,7 @@ namespace ComPDFKit.Controls.PDFControl
                     pdfContentEditControl.SetPDFTextEditData(new List<TextEditParam> { (TextEditParam)pDFEditParam }, true);
                     PropertyContainer.Child = pdfContentEditControl;
                 }
-                else if (editAreaArea.Type == CPDFEditType.EditImage && PdfViewControl != null)
+                else if (editAreaArea.Type == CPDFEditType.EditImage)
                 {
                     UIElement pageView = sender as UIElement;
                     if (pageView != null)
@@ -806,6 +814,18 @@ namespace ComPDFKit.Controls.PDFControl
                     pdfContentEditControl.SetPDFImageEditData(new List<ImageEditParam> { (ImageEditParam)pDFEditParam });
                     PropertyContainer.Child = pdfContentEditControl;
                 }
+                else if (editAreaArea.Type == CPDFEditType.EditPath)
+                {
+                    UIElement pageView = sender as UIElement;
+                    if (pageView != null)
+                    {
+                        pageView.MouseLeftButtonUp -= PageView_MouseLeftButtonUp;
+                        pageView.MouseLeftButtonUp += PageView_MouseLeftButtonUp;
+                    }
+                    PDFEditParam pDFEditParam = ParamConverter.CPDFDataConverterToPDFEitParam(PdfViewControl.PDFToolManager.GetDocument(), editAreaArea, pageIndex);
+                    pdfContentEditControl.SetPDFPathEditData(new List<PathEditParam> { (PathEditParam)pDFEditParam });
+                    PropertyContainer.Child = pdfContentEditControl;
+                }
             }
         }
 

+ 9 - 3
Demo/Examples/Compdfkit.Controls/Edit/PDFContentEditControl.xaml.cs

@@ -8,9 +8,9 @@ namespace ComPDFKit.Controls.Edit
     public partial class PDFContentEditControl : UserControl
     {
         #region  
-
         private PDFImageEditControl PDFImageEditControl = new PDFImageEditControl();
         private PDFTextEditControl PDFTextEditControl = new PDFTextEditControl();
+        private PDFPathEditControl PDFPathEditControl = new PDFPathEditControl();
 
         public PDFViewControl ViewControl { get; private set; }
         public PDFEditParam EditEvent { get; set; }
@@ -24,10 +24,11 @@ namespace ComPDFKit.Controls.Edit
         public void InitWithPDFViewer(PDFViewControl newPDFView)
         {
             ViewControl = newPDFView;
-            PDFImageEditControl.InitWithPDFViewer(newPDFView.PDFViewTool);
             PDFTextEditControl.InitWithPDFViewer(newPDFView.PDFViewTool);
+            PDFImageEditControl.InitWithPDFViewer(newPDFView.PDFViewTool);
+            PDFPathEditControl.InitWithPDFViewer(newPDFView.PDFViewTool);
         }
-         
+
         public void SetRotationText(float rotation)
         {
             PDFImageEditControl.SetRotationText(rotation);
@@ -66,6 +67,11 @@ namespace ComPDFKit.Controls.Edit
             ContentEditContainer.Child = PDFImageEditControl;
         }
 
+        public void SetPDFPathEditData(List<PathEditParam> editEvent)
+        {
+            PDFPathEditControl.SetPDFPathEditData(editEvent);
+            ContentEditContainer.Child = PDFPathEditControl;
+        }
 
         //public void SetPDFImageMultiEditData(List<PDFEditEvent> editEventList)
         //{

+ 122 - 0
Demo/Examples/Compdfkit.Controls/Edit/PDFPathEdit/PDFPathEditControl/PDFPathEditControl.xaml

@@ -0,0 +1,122 @@
+<UserControl x:Class="ComPDFKit.Controls.Edit.PDFPathEditControl"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:ComPDFKit.Controls.Edit"
+             xmlns:common="clr-namespace:ComPDFKit.Controls.Common"
+             mc:Ignorable="d" 
+             d:DesignHeight="720" d:DesignWidth="280" MinWidth="260" Padding="10"
+             Background="#FAFCFF">
+    <UserControl.Resources>
+        <ResourceDictionary>
+            <ResourceDictionary.MergedDictionaries>
+                <ResourceDictionary Source="../../../Asset/Styles/ButtonStyle.xaml"></ResourceDictionary>
+                <ResourceDictionary Source="../../../Asset/Styles/SliderStyle.xaml"></ResourceDictionary>
+            </ResourceDictionary.MergedDictionaries>
+            <common:PropertyPanelResourceConverter x:Key="PropertyPanelResourceConverter"></common:PropertyPanelResourceConverter>
+            <common:CommonResourceConverter x:Key="CommonResourceConverter" />
+        </ResourceDictionary>
+    </UserControl.Resources>
+    <ScrollViewer VerticalScrollBarVisibility="Auto">
+        <StackPanel>
+            <Border Background="White" Height="36">
+                <TextBlock FontSize="14" FontWeight="Bold" HorizontalAlignment="Center" Foreground="#42464D" VerticalAlignment="Center" Text="Path属性"></TextBlock>
+            </Border>
+
+            <StackPanel Grid.Row="1">
+                <TextBlock Margin="0,20,0,0" Foreground="#0E1114" FontSize="14"
+                       Text="边框颜色"></TextBlock>
+                <common:ColorPickerControl x:Name="StrokeColorUI" Grid.Row="1" Margin="0,20,0,0" TransparentBtnProperty="Collapsed"></common:ColorPickerControl>
+                <TextBlock Margin="0,20,0,0" Foreground="#0E1114" FontSize="14"
+                       Text="填充颜色"></TextBlock>
+
+                <common:ColorPickerControl x:Name="FillColorUI" Grid.Row="1" Margin="0,20,0,0" TransparentBtnProperty="Collapsed"></common:ColorPickerControl>
+            </StackPanel>
+
+            <StackPanel Grid.Row="2">
+                <local:CPDFImageRotateUI x:Name="RotateUI" FontSize="16"></local:CPDFImageRotateUI>
+                <Grid Margin="0,10,0,0">
+                    <TextBlock Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Rotation}" FontFamily="Microsoft YaHei" FontSize="14" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock>
+                    <TextBox Padding="5,0,5,0" x:Name="RotationTxb" HorizontalAlignment="Right" VerticalContentAlignment="Center" Width="110" Height="32" LostFocus="RotationTxb_LostFocus" PreviewKeyDown="RotationTxb_PreviewKeyDown"></TextBox>
+                </Grid>
+            </StackPanel>
+
+            <local:CPDFImageFlipUI x:Name="FlipUI" Grid.Row="3" FontSize="16" Margin="0,10,0,0"></local:CPDFImageFlipUI>
+
+            <Grid Grid.Row="4" Margin="0,20,0,0">
+                <Grid.ColumnDefinitions>
+                    <ColumnDefinition Width="*"></ColumnDefinition>
+                    <ColumnDefinition Width="auto"></ColumnDefinition>
+                </Grid.ColumnDefinitions>
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="auto"></RowDefinition>
+                    <RowDefinition Height="auto"></RowDefinition>
+                </Grid.RowDefinitions>
+
+                <TextBlock FontSize="14" Foreground="#43474D" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Opacity}"></TextBlock>
+
+                <Slider Style="{StaticResource SliderStyle}" Grid.Row="1" Width="148" Height="28"
+                    Name="PathOpacitySlider" 
+                    Value="14"  
+                    IsSelectionRangeEnabled="True" 
+                    IsMoveToPointEnabled="True" 
+                    Margin="2,20,2,0"  
+                    Maximum="1" 
+                    Minimum="0" 
+                    TickFrequency="0.01"
+                    IsSnapToTickEnabled="True" 
+                    Thumb.DragCompleted="SliderOpacity_DragCompleted"
+                    Thumb.DragStarted="Slider_DragStarted"
+                    ValueChanged="SliderOpacity_ValueChanged"
+                    Tag="true"
+                    />
+
+                <Grid Grid.Row="1" Grid.Column="1" Margin="0,10,0,0">
+                    <ComboBox Name="OpacityComboBox" VerticalContentAlignment="Center" Width="72" Height="28" Foreground="#43474D" FontSize="14"
+                              SelectionChanged="OpacityComboBox_SelectionChanged" BorderBrush="#1E000000">
+                        <ComboBoxItem>25%</ComboBoxItem>
+                        <ComboBoxItem>50%</ComboBoxItem>
+                        <ComboBoxItem>75%</ComboBoxItem>
+                        <ComboBoxItem>100%</ComboBoxItem>
+                    </ComboBox>
+                    <TextBox Name="OpacityTextBox" IsHitTestVisible="False" Width="72" Height="30" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
+                             IsReadOnly="True" Background="White" Padding="0,0,15,0" FontSize="14">100%</TextBox>
+                    <Path Fill="#43474D" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,5,0" IsHitTestVisible="False">
+                        <Path.Data>
+                            M0.5 0.510248L4.5041 5.5L8.5 0.5L0.5 0.510248Z
+                        </Path.Data>
+                    </Path>
+                </Grid>
+            </Grid>
+
+            <Grid  Margin="0,20,0,0" Visibility="{Binding OnlySingleVisible}">
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="auto"></RowDefinition>
+                    <RowDefinition Height="auto"></RowDefinition>
+                </Grid.RowDefinitions>
+                <TextBlock VerticalAlignment="Center" FontSize="14" Foreground="#43474D" Text="{Binding Converter={StaticResource PropertyPanelResourceConverter},ConverterParameter=Property_Tool}"></TextBlock>
+
+                <Border Grid.Row="1" BorderThickness="1" BorderBrush="#E1E3E5"  Margin="0,14,0,0" HorizontalAlignment="Left">
+                    <StackPanel Orientation="Horizontal">
+                        <Button Name="PathClipBtn" Grid.Column="1" Width="40" Height="25" BorderThickness="0" Click="PathClipBtn_Click" Background="White" Style="{StaticResource LightButtonStyle}"
+                            ToolTip="{Binding Converter={StaticResource CommonResourceConverter},ConverterParameter=Menu_Crop}">
+                            <Button.Content>
+                                <Path Fill="#43474D">
+                                    <Path.Data>
+                                        M4.75 15.75V4.25H14.4074L13.9517 4.73826L15.0483 5.76174L15.25 5.54562V15.75H4.75ZM3.25 
+                                16.5V4.25H0V2.75H3.25V0.5H4.75V2.75H16H16.75V3.5V15.75H20V17.25H16.75V19.5H15.25V17.25H4H3.25V16.5ZM17.8483 2.76174L18.5483 
+                                2.01174L17.4517 0.988261L16.7517 1.73826L17.8483 2.76174ZM12.2483 8.76174L13.6483 7.26174L12.5517 6.23826L11.1517 7.73826L12.2483 
+                                8.76174ZM9.44829 11.7617L10.8483 10.2617L9.75171 9.23826L8.35171 10.7383L9.44829 11.7617ZM6.64829 14.7617L8.04829 13.2617L6.95171 
+                                12.2383L5.55171 13.7383L6.64829 14.7617Z
+                                    </Path.Data>
+                                </Path>
+                            </Button.Content>
+                        </Button>
+                    </StackPanel>
+                </Border>
+
+            </Grid>
+        </StackPanel>
+    </ScrollViewer>
+</UserControl>

+ 604 - 0
Demo/Examples/Compdfkit.Controls/Edit/PDFPathEdit/PDFPathEditControl/PDFPathEditControl.xaml.cs

@@ -0,0 +1,604 @@
+using ComPDFKit.Import;
+using ComPDFKit.PDFDocument;
+using ComPDFKit.PDFPage;
+using ComPDFKit.PDFPage.Edit;
+using ComPDFKit.Tool;
+using ComPDFKit.Tool.UndoManger;
+using ComPDFKit.Viewer.Helper;
+using ComPDFKitViewer;
+using System;
+using System.Collections.Generic;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Input;
+using ComPDFKit.Tool.DrawTool;
+using ComPDFKitViewer.Helper;
+using System.Linq;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using ComPDFKit.Tool.SettingParam;
+using System.Windows.Media;
+
+namespace ComPDFKit.Controls.Edit
+{
+    public partial class PDFPathEditControl : UserControl, INotifyPropertyChanged
+    {
+        #region property
+        public CPDFViewerTool ToolView { get; set; }
+        public List<PathEditParam> EditEvents { get; set; } = new List<PathEditParam>();
+
+        private Visibility _onlySingleVisible = Visibility.Collapsed;
+        public Visibility OnlySingleVisible
+        {
+            get => _onlySingleVisible;
+            set => UpdateProper(ref _onlySingleVisible, value);
+        }
+
+        #endregion 
+
+        public PDFPathEditControl()
+        {
+            DataContext = this;
+            InitializeComponent();
+            Loaded += PDPathEditControl_Loaded;
+            Unloaded += PDFPathEditControl_Unloaded;
+        }
+
+        #region Load unload custom control
+
+        private void PDPathEditControl_Loaded(object sender, RoutedEventArgs e)
+        {
+            RotateUI.RotationChanged -= RotateUI_RotationChanged;
+            FlipUI.FlipChanged -= FlipUI_FlipChanged;
+            RotateUI.RotationChanged += RotateUI_RotationChanged;
+            FlipUI.FlipChanged += FlipUI_FlipChanged;
+            ToolView.SelectedDataChanged -= ToolView_SelectedDataChanged;
+            ToolView.SelectedDataChanged += ToolView_SelectedDataChanged;
+
+            StrokeColorUI.ColorChanged -= StrokeColorUI_ColorChanged;
+            StrokeColorUI.ColorChanged += StrokeColorUI_ColorChanged;
+
+            FillColorUI.ColorChanged -= FillColorUI_ColorChanged;
+            FillColorUI.ColorChanged += FillColorUI_ColorChanged;
+        }
+
+        private void StrokeColorUI_ColorChanged(object sender, EventArgs e)
+        {
+            SolidColorBrush newBrush = StrokeColorUI.Brush as SolidColorBrush;
+            GetPathArea(out List<CPDFEditPathArea> pathAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (pathAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
+            {
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(pathAreas[0].GetFrame());
+                bool result = pathAreas[0].SetStrokeColor(new byte[] { newBrush.Color.R, newBrush.Color.G, newBrush.Color.B});
+                if (result)
+                {
+                    PDFEditHistory editHistory = new PDFEditHistory();
+                    editHistory.EditPage = editPage;
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, pathAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditPathArea pathArea in pathAreas)
+                {
+                    if (pathArea.SetStrokeColor(new byte[] { newBrush.Color.R, newBrush.Color.G, newBrush.Color.B }))
+                    {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
+                        editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
+                    }
+
+                    ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                    ToolView.GetCPDFViewer()?.UpdateRenderFrame();
+                }
+            }
+
+            editPage.EndEdit();
+            if (EditEvents.Count > 0 && newBrush != null)
+            {
+                byte[] Color = new byte[3];
+                Color[0] = newBrush.Color.R;
+                Color[1] = newBrush.Color.G;
+                Color[2] = newBrush.Color.B;
+                EditEvents.FirstOrDefault().StrokeColor = Color;
+                DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
+                defaultSettingParam.SetPDFEditParamm(EditEvents.FirstOrDefault());
+            }
+        }
+
+        private void FillColorUI_ColorChanged(object sender, EventArgs e)
+        {
+            SolidColorBrush newBrush = FillColorUI.Brush as SolidColorBrush;
+            GetPathArea(out List<CPDFEditPathArea> pathAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (pathAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
+            {
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(pathAreas[0].GetFrame());
+                bool result = pathAreas[0].SetFillColor(new byte[] { newBrush.Color.R, newBrush.Color.G, newBrush.Color.B });
+                if (result)
+                {
+                    PDFEditHistory editHistory = new PDFEditHistory();
+                    editHistory.EditPage = editPage;
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, pathAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditPathArea pathArea in pathAreas)
+                {
+                    if (pathArea.SetFillColor(new byte[] { newBrush.Color.R, newBrush.Color.G, newBrush.Color.B }))
+                    {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
+                        editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
+                    }
+
+                    ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                    ToolView.GetCPDFViewer()?.UpdateRenderFrame();
+                }
+            }
+
+            editPage.EndEdit();
+            if (EditEvents.Count > 0 && newBrush != null)
+            {
+                byte[] Color = new byte[3];
+                Color[0] = newBrush.Color.R;
+                Color[1] = newBrush.Color.G;
+                Color[2] = newBrush.Color.B;
+                EditEvents.FirstOrDefault().FillColor = Color;
+                DefaultSettingParam defaultSettingParam = ToolView.GetDefaultSettingParam();
+                defaultSettingParam.SetPDFEditParamm(EditEvents.FirstOrDefault());
+            }
+        }
+
+        private void PDFPathEditControl_Unloaded(object sender, RoutedEventArgs e)
+        {
+            RotateUI.RotationChanged -= RotateUI_RotationChanged;
+            FlipUI.FlipChanged -= FlipUI_FlipChanged;
+        }
+
+        #endregion
+
+        #region Property changed
+
+        private void PathCut()
+        {
+            GetPathArea(out List<CPDFEditPathArea> pathAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (pathAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            SelectedRect selectedRect = ToolView.GetSelectedRectForEditAreaObject(pathAreas[0]);
+            if (selectedRect == null)
+                return;
+
+            Rect oldRect = DataConversionForWPF.CRectConversionForRect(pathAreas[0].GetFrame());
+            double currentZoom = ToolView.GetCPDFViewer().CurrentRenderFrame.ZoomFactor;
+            Rect rect = selectedRect.GetRect();
+            Rect maxRect = selectedRect.GetMaxRect();
+            Rect pdfRect = new Rect((rect.X - maxRect.X) / currentZoom, (rect.Y - maxRect.Y) / currentZoom, rect.Width / currentZoom, rect.Height / currentZoom);
+            pdfRect = DpiHelper.StandardRectToPDFRect(pdfRect);
+            CRect newCRect = new CRect((float)pdfRect.Left, (float)pdfRect.Bottom, (float)pdfRect.Right, (float)pdfRect.Top);
+            if (pathAreas[0].CutWithRect(newCRect))
+            {
+                PDFEditHistory editHistory = new PDFEditHistory();
+                editHistory.EditPage = editPage;
+                editHistory.PageIndex = pdfPage.PageIndex;
+
+                ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                ToolView.UpdateRender(oldRect, pathAreas[0]);
+            }
+
+            editPage.EndEdit();
+        }
+
+        private void ToolView_SelectedDataChanged(object sender, SelectedAnnotData e)
+        {
+            if (ToolView.GetIsCropMode())
+            {
+                PathCut();
+            }
+        }
+
+        #endregion
+
+        #region Init PDFViewer
+        public void InitWithPDFViewer(CPDFViewerTool newPDFView)
+        {
+            ToolView = newPDFView;
+        }
+        #endregion
+
+        #region public method
+
+        //public void SetRotationText(float rotation)
+        //{
+        //    RotationTxb.Text = rotation.ToString(CultureInfo.CurrentCulture);
+        //}
+
+        #endregion
+
+        #region Path Edit
+
+        private void SetPathTransparency(double transparency)
+        {
+            PathOpacitySlider.Value = transparency / 255D;
+            OpacityTextBox.Text = string.Format("{0}%", (int)(Math.Round(PathOpacitySlider.Value * 100)));
+        }
+
+        public void SetPDFPathEditData(List<PathEditParam> newEvents)
+        {
+            EditEvents = newEvents.Where(newEvent => newEvent.EditIndex >= 0 && newEvent.EditType == CPDFEditType.EditPath).ToList();
+            if (EditEvents.Count == 0)
+                return;
+
+            PathEditParam defaultEvent = EditEvents.FirstOrDefault();
+
+            SetPathTransparency(defaultEvent.Transparency);
+            RotationTxb.Text = defaultEvent.Rotate.ToString();
+
+            StrokeColorUI.SetCheckedForColor(Color.FromRgb(
+            defaultEvent.StrokeColor[0],
+            defaultEvent.StrokeColor[1],
+            defaultEvent.StrokeColor[2]));
+
+            FillColorUI.SetCheckedForColor(Color.FromRgb(
+            defaultEvent.FillColor[0],
+            defaultEvent.FillColor[1],
+            defaultEvent.FillColor[2]));
+
+            if (EditEvents.Count == 1)
+            {
+                OnlySingleVisible = Visibility.Visible;
+            }
+            else
+            {
+                OnlySingleVisible = Visibility.Collapsed;
+            }
+        }
+
+        #endregion
+
+        #region Property changed
+
+        private void FlipUI_FlipChanged(object sender, bool e)
+        {
+            GetPathArea(out List<CPDFEditPathArea> pathAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (pathAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
+            {
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(pathAreas[0].GetFrame());
+                bool result;
+                if (e)
+                {
+                    result = pathAreas[0].VerticalMirror();
+                }
+                else
+                {
+                    result = pathAreas[0].HorizontalMirror();
+                }
+
+                if (result)
+                {
+                    PDFEditHistory editHistory = new PDFEditHistory();
+                    editHistory.EditPage = editPage;
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, pathAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditPathArea pathArea in pathAreas)
+                {
+                    bool result;
+                    if (e)
+                    {
+                        result = pathArea.VerticalMirror();
+                    }
+                    else
+                    {
+                        result = pathArea.HorizontalMirror();
+                    }
+
+                    if (result)
+                    {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
+                        editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
+                    }
+                }
+
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
+            }
+
+            editPage.EndEdit();
+        }
+
+        private void RotateUI_RotationChanged(object sender, double e)
+        {
+            GetPathArea(out List<CPDFEditPathArea> pathAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (pathAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
+            {
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(pathAreas[0].GetFrame());
+                if (pathAreas[0].Rotate((int)-e))
+                {
+                    PDFEditHistory editHistory = new PDFEditHistory();
+                    editHistory.EditPage = editPage;
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, pathAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditPathArea pathArea in pathAreas)
+                {
+                    if (pathArea.Rotate((int)-e))
+                    {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
+                        editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
+                    }
+                }
+
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
+            }
+
+            editPage.EndEdit();
+            RotationTxb.Text = pathAreas.FirstOrDefault().GetRotation().ToString();
+        }
+
+        private void Slider_DragStarted(object sender, DragStartedEventArgs e)
+        {
+            Slider slider = sender as Slider;
+            if (slider != null)
+            {
+                slider.Tag = "false";
+            }
+        }
+
+        private void SliderOpacity_DragCompleted(object sender, DragCompletedEventArgs e)
+        {
+            Slider slider = sender as Slider;
+            if (slider != null)
+            {
+                slider.Tag = "true";
+            }
+
+            GetPathArea(out List<CPDFEditPathArea> pathAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (pathAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
+            {
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(pathAreas[0].GetFrame());
+                if (pathAreas[0].SetTransparency((byte)(PathOpacitySlider.Value * 255)))
+                {
+                    PDFEditHistory editHistory = new PDFEditHistory();
+                    editHistory.EditPage = editPage;
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, pathAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditPathArea pathArea in pathAreas)
+                {
+                    if (pathArea.SetTransparency((byte)(PathOpacitySlider.Value * 255)))
+                    {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
+                        editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
+                    }
+                }
+
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
+            }
+
+            editPage.EndEdit();
+        }
+
+        private void SliderOpacity_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
+        {
+            Slider slider = sender as Slider;
+            if (OpacityTextBox != null)
+            {
+                OpacityTextBox.Text = string.Format("{0}%", (int)(PathOpacitySlider.Value * 100));
+            }
+
+            if (slider != null && slider.Tag != null && slider.Tag.ToString() == "false")
+            {
+                return;
+            }
+
+            GetPathArea(out List<CPDFEditPathArea> pathAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (pathAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
+            {
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(pathAreas[0].GetFrame());
+                if (pathAreas[0].SetTransparency((byte)(PathOpacitySlider.Value * 255)))
+                {
+                    PDFEditHistory editHistory = new PDFEditHistory();
+                    editHistory.EditPage = editPage;
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, pathAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditPathArea pathArea in pathAreas)
+                {
+                    if (pathArea.SetTransparency((byte)(PathOpacitySlider.Value * 255)))
+                    {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
+                        editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
+                    }
+                }
+
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
+            }
+
+            editPage.EndEdit();
+        }
+
+        private void PathClipBtn_Click(object sender, RoutedEventArgs e)
+        {
+            ToolView.SetCropMode(!ToolView.GetIsCropMode());
+        }
+
+        private void OpacityComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            ComboBoxItem selectItem = OpacityComboBox.SelectedItem as ComboBoxItem;
+            if (selectItem != null && selectItem.Content != null)
+            {
+                if (double.TryParse(selectItem.Content.ToString().TrimEnd('%'), out double newOpacity))
+                {
+                    OpacityTextBox.Text = selectItem.Content.ToString();
+                    PathOpacitySlider.Value = newOpacity / 100.0;
+                }
+            }
+        }
+
+        private void GetPathArea(out List<CPDFEditPathArea> pathAreas, out CPDFPage pdfPage, out CPDFEditPage editPage)
+        {
+            pathAreas = new List<CPDFEditPathArea>();
+            editPage = null;
+            pdfPage = null;
+            if (ToolView == null || EditEvents.Count == 0)
+            {
+                return;
+            }
+
+            try
+            {
+                foreach (var EditEvent in EditEvents)
+                {
+                    CPDFViewer pdfViewer = ToolView.GetCPDFViewer();
+                    CPDFDocument pdfDoc = pdfViewer.GetDocument();
+                    pdfPage = pdfDoc.PageAtIndex(EditEvent.PageIndex);
+                    editPage = pdfPage.GetEditPage();
+                    List<CPDFEditArea> editAreas = editPage.GetEditAreaList();
+                    if (editAreas != null && editAreas.Count > EditEvent.EditIndex)
+                    {
+                        pathAreas.Add(editAreas[EditEvent.EditIndex] as CPDFEditPathArea);
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+
+            }
+        }
+
+        private void SetAbsRotation(double absRotation)
+        {
+            GetPathArea(out List<CPDFEditPathArea> pathAreas, out CPDFPage pdfPage, out CPDFEditPage editPage);
+            if (pathAreas.Count == 0 || pdfPage == null || editPage == null)
+                return;
+
+            if (ToolView.CurrentEditAreaObject() != null)
+            {
+                Rect oldRect = DataConversionForWPF.CRectConversionForRect(pathAreas[0].GetFrame());
+                int rotation = (int)absRotation - pathAreas[0].GetRotation();
+                if (pathAreas[0].Rotate(rotation))
+                {
+                    PDFEditHistory editHistory = new PDFEditHistory();
+                    editHistory.EditPage = editPage;
+                    editHistory.PageIndex = pdfPage.PageIndex;
+                    ToolView.GetCPDFViewer().UndoManager.AddHistory(editHistory);
+                    ToolView.UpdateRender(oldRect, pathAreas[0]);
+                }
+            }
+            else
+            {
+                GroupHistory groupHistory = new GroupHistory();
+                foreach (CPDFEditPathArea pathArea in pathAreas)
+                {
+                    int rotation = (int)absRotation - pathArea.GetRotation();
+                    if (pathArea.Rotate(rotation))
+                    {
+                        PDFEditHistory editHistory = new PDFEditHistory();
+                        editHistory.EditPage = editPage;
+                        editHistory.PageIndex = pdfPage.PageIndex;
+                        groupHistory.Histories.Add(editHistory);
+                    }
+                }
+
+                ToolView.GetCPDFViewer()?.UndoManager.AddHistory(groupHistory);
+                ToolView.GetCPDFViewer()?.UpdateRenderFrame();
+            }
+
+            editPage.EndEdit();
+        }
+
+        private void RotationTxb_LostFocus(object sender, RoutedEventArgs e)
+        {
+            if (!double.TryParse(RotationTxb.Text, out double rotation))
+            {
+                return;
+            }
+            SetAbsRotation(rotation);
+        }
+
+        private void RotationTxb_PreviewKeyDown(object sender, KeyEventArgs e)
+        {
+            if (e.Key == Key.Enter)
+            {
+                RotationTxb_LostFocus(null, null);
+            }
+        }
+        #endregion
+
+        public event PropertyChangedEventHandler PropertyChanged;
+        protected bool UpdateProper<T>(ref T properValue,
+                                           T newValue,
+                                           [CallerMemberName] string properName = "")
+        {
+            if (object.Equals(properValue, newValue))
+                return false;
+
+            properValue = newValue;
+            OnPropertyChanged(properName);
+            return true;
+        }
+
+        protected void OnPropertyChanged([CallerMemberName] string propertyName = "") =>
+        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+    }
+}