using ComPDFKit.Measure;
using ComPDFKit.PDFAnnotation;
using Compdfkit_Tools.Helper;
using Compdfkit_Tools.PDFControl;
using ComPDFKitViewer;
using ComPDFKitViewer.AnnotEvent;
using ComPDFKitViewer.PdfViewer;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
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.Navigation;
using System.Windows.Shapes;
namespace Compdfkit_Tools.Measure
{
///
/// MeasureControl.xaml 的交互逻辑
///
public partial class MeasureControl : UserControl
{
public MeasurePropertyControl measurePropertyControl = new MeasurePropertyControl();
private CPDFDisplaySettingsControl displaySettingsControl;
private PDFViewControl PdfViewControl = new PDFViewControl();
private PanelState panelState = PanelState.GetInstance();
public event EventHandler ExpandEvent;
public MeasureControl()
{
InitializeComponent();
MeasureSetting.MeasureChanged += MeasureSetting_MeasureChanged;
}
private void MeasureSetting_MeasureChanged(object sender, MeasureEventArgs e)
{
InfoPanel.SetMeasureType(e.Type);
InfoPanel.SetMeasureInfo(e);
switch (e.Type)
{
case CPDFMeasureType.CPDF_DISTANCE_MEASURE:
case CPDFMeasureType.CPDF_PERIMETER_MEASURE:
SettingPanel.ShowAreaAndLength(Visibility.Collapsed);
break;
case CPDFMeasureType.CPDF_AREA_MEASURE:
SettingPanel.ShowAreaAndLength(Visibility.Visible);
break;
default:
break;
}
SettingPanel.BindMeasureSetting(e);
}
#region Init PDFViewer
public void InitWithPDFViewer(PDFViewControl pdfViewControl, CPDFViewer pdfViewer)
{
PdfViewControl = pdfViewControl;
PdfViewControl.PDFView = pdfViewer;
PDFMeasureTool.InitWithPDFViewer(pdfViewer, measurePropertyControl, this);
FloatPageTool.InitWithPDFViewer(pdfViewer);
PDFGrid.Child = PdfViewControl;
panelState.PropertyChanged -= PanelState_PropertyChanged;
panelState.PropertyChanged += PanelState_PropertyChanged;
pdfViewControl.PDFView.AnnotActiveHandler -= PDFView_AnnotActiveHandler;
pdfViewControl.PDFView.AnnotActiveHandler += PDFView_AnnotActiveHandler;
pdfViewControl.PDFView.AnnotCommandHandler -= PDFView_AnnotCommandHandler;
pdfViewControl.PDFView.AnnotCommandHandler += PDFView_AnnotCommandHandler;
SetInfoPanelVisble(false, false);
SettingPanel.PdfViewControl= pdfViewControl;
}
private void PDFView_AnnotCommandHandler(object sender, AnnotCommandArgs e)
{
switch (e.CommandType)
{
case CommandType.Context:
if (e.CommandTarget == TargetType.Annot && e.PressOnAnnot)
{
e.Handle = true;
e.PopupMenu = new ContextMenu();
e.PopupMenu.Items.Add(new MenuItem() { Header = "Delete", Command = ApplicationCommands.Delete, CommandTarget = (UIElement)sender });
MenuItem menuItem = new MenuItem();
menuItem.Header = "Measurement Settings";
menuItem.Click += (item, param) =>
{
SettingPanel.UpdateArgsList = e.AnnotEventArgsList;
SettingPanel.BindMeasureSetting();
SetInfoPanelVisble(false, true);
};
MenuItem propertyItem = new MenuItem();
propertyItem.Header = "Properties";
propertyItem.Click += (item, param) =>
{
ExpandEvent?.Invoke(this, new EventArgs());
};
e.PopupMenu.Items.Add(menuItem);
e.PopupMenu.Items.Add(propertyItem);
}
break;
case CommandType.Delete:
e.DoCommand();
break;
default:
break;
}
}
private void PDFView_AnnotActiveHandler(object sender, AnnotAttribEvent e)
{
if (e == null || e.IsAnnotCreateReset)
{
if (e == null)
{
measurePropertyControl?.ClearMeasurePanel();
if(PDFMeasureTool.ToolChecked()==false)
{
SetInfoPanelVisble(false, false);
}
}
return;
}
else
{
switch (e.GetAnnotTypes())
{
case AnnotArgsType.LineMeasure:
LineMeasureArgs LineArgs = e.GetAnnotHandlerEventArgs(AnnotArgsType.LineMeasure).First() as LineMeasureArgs;
panelState.RightPanel = PanelState.RightPanelState.PropertyPanel;
measurePropertyControl.SetPropertyForMeasureCreate(LineArgs, e);
SetInfoPanelVisble(true, false);
SetMeasureInfoPanel(LineArgs.GetPDFAnnot(), LineArgs);
break;
case AnnotArgsType.PolygonMeasure:
PolygonMeasureArgs polygonArgs = e.GetAnnotHandlerEventArgs(AnnotArgsType.PolygonMeasure).First() as PolygonMeasureArgs;
panelState.RightPanel = PanelState.RightPanelState.PropertyPanel;
measurePropertyControl.SetPropertyForMeasureCreate(polygonArgs, e);
SetInfoPanelVisble(true, false);
SetMeasureInfoPanel(polygonArgs.GetPDFAnnot(),polygonArgs);
break;
case AnnotArgsType.PolyLineMeasure:
PolyLineMeasureArgs polyLineArgs = e.GetAnnotHandlerEventArgs(AnnotArgsType.PolyLineMeasure).First() as PolyLineMeasureArgs;
panelState.RightPanel = PanelState.RightPanelState.PropertyPanel;
measurePropertyControl.SetPropertyForMeasureCreate(polyLineArgs, e);
SetInfoPanelVisble(true, false);
SetMeasureInfoPanel(polyLineArgs.GetPDFAnnot(),polyLineArgs);
break;
}
}
}
private void SetMeasureInfoPanel(CPDFAnnotation rawAnnot,AnnotHandlerEventArgs annotArgs=null)
{
if (rawAnnot == null)
{
return;
}
try
{
if (rawAnnot.Type == C_ANNOTATION_TYPE.C_ANNOTATION_LINE)
{
CPDFLineAnnotation lineAnnot = rawAnnot as CPDFLineAnnotation;
if (lineAnnot.IsMersured() && lineAnnot.Points != null && lineAnnot.Points.Count() == 2)
{
CPDFDistanceMeasure lineMeasure = lineAnnot.GetDistanceMeasure();
CPDFMeasureInfo measureInfo = lineMeasure.MeasureInfo;
Vector standVector = new Vector(1, 0);
Point startPoint = new Point(lineAnnot.Points[0].x, lineAnnot.Points[0].y);
Point endPoint = new Point(lineAnnot.Points[1].x, lineAnnot.Points[1].y);
Vector movevector = endPoint - startPoint;
double showLenght=lineMeasure.GetMeasurementResults(CPDFCaptionType.CPDF_CAPTION_LENGTH);
MeasureEventArgs measureEvent = new MeasureEventArgs();
measureEvent.Angle = (int)Math.Abs(Vector.AngleBetween(movevector, standVector));
measureEvent.RulerTranslateUnit = measureInfo.RulerTranslateUnit;
measureEvent.RulerTranslate = measureInfo.RulerTranslate;
measureEvent.RulerBase = measureInfo.RulerBase;
measureEvent.RulerBaseUnit = measureInfo.RulerBaseUnit;
measureEvent.MousePos = new Point(
(int)Math.Abs(movevector.X),
(int)Math.Abs(movevector.Y));
measureEvent.Type = CPDFMeasureType.CPDF_DISTANCE_MEASURE;
NumberFormatInfo formatInfo = new NumberFormatInfo();
formatInfo.NumberDecimalDigits = Math.Abs(measureInfo.Precision).ToString().Length - 1;
measureEvent.Distance = showLenght.ToString("N", formatInfo) + " " + measureInfo.RulerTranslateUnit;
measureEvent.Precision = GetMeasureShowPrecision(measureInfo.Precision);
MeasureSetting.InvokeMeasureChangeEvent(this, measureEvent);
if(annotArgs!=null)
{
SettingPanel.UpdateArgsList =new List { annotArgs};
}
}
}
if (rawAnnot.Type == C_ANNOTATION_TYPE.C_ANNOTATION_POLYLINE)
{
CPDFPolylineAnnotation polylineAnnot = rawAnnot as CPDFPolylineAnnotation;
if (polylineAnnot.IsMersured() && polylineAnnot.Points != null && polylineAnnot.Points.Count() >= 2)
{
double totalInch = 0;
for (int i = 0; i < polylineAnnot.Points.Count - 1; i++)
{
Point endLinePoint = new Point(
polylineAnnot.Points[i + 1].x,
polylineAnnot.Points[i + 1].y
);
Point startLinePoint = new Point(
polylineAnnot.Points[i].x,
polylineAnnot.Points[i].y
);
Vector subVector = endLinePoint - startLinePoint;
totalInch += subVector.Length;
}
totalInch = totalInch / 72D;
CPDFPerimeterMeasure lineMeasure = polylineAnnot.GetPerimeterMeasure();
CPDFMeasureInfo measureInfo = lineMeasure.MeasureInfo;
double showLenght = lineMeasure.GetMeasurementResults(CPDFCaptionType.CPDF_CAPTION_LENGTH);
MeasureEventArgs measureEvent = new MeasureEventArgs();
measureEvent.Angle = 0;
measureEvent.RulerTranslateUnit = measureInfo.RulerTranslateUnit;
measureEvent.RulerTranslate = measureInfo.RulerTranslate;
measureEvent.RulerBase = measureInfo.RulerBase;
measureEvent.RulerBaseUnit = measureInfo.RulerBaseUnit;
measureEvent.Precision = GetMeasureShowPrecision(measureInfo.Precision);
measureEvent.Type = CPDFMeasureType.CPDF_PERIMETER_MEASURE;
NumberFormatInfo formatInfo = new NumberFormatInfo();
formatInfo.NumberDecimalDigits = Math.Abs(measureInfo.Precision).ToString().Length - 1;
measureEvent.Distance = showLenght.ToString("N", formatInfo) +" "+ measureInfo.RulerTranslateUnit;
MeasureSetting.InvokeMeasureChangeEvent(this, measureEvent);
if (annotArgs != null)
{
SettingPanel.UpdateArgsList = new List { annotArgs };
}
}
}
if(rawAnnot.Type== C_ANNOTATION_TYPE.C_ANNOTATION_POLYGON)
{
CPDFPolygonAnnotation Annot = rawAnnot as CPDFPolygonAnnotation;
CPDFAreaMeasure polygonMeasure = Annot.GetAreaMeasure();
CPDFMeasureInfo measureInfo = polygonMeasure.MeasureInfo;
CPDFCaptionType CaptionType = measureInfo.CaptionType;
bool IsArea = false;
bool IsLength = false;
if ((CaptionType& CPDFCaptionType.CPDF_CAPTION_AREA)== CPDFCaptionType.CPDF_CAPTION_AREA)
{
IsArea = true;
}
if ((CaptionType & CPDFCaptionType.CPDF_CAPTION_LENGTH) == CPDFCaptionType.CPDF_CAPTION_LENGTH)
{
IsLength = true;
}
SettingPanel.ChangedCheckBoxIsChecked(IsArea, IsLength);
double inch = polygonMeasure.GetMeasurementResults(CPDFCaptionType.CPDF_CAPTION_AREA);
double currentInch = polygonMeasure.GetMeasurementResults(CPDFCaptionType.CPDF_CAPTION_LENGTH);
MeasureEventArgs measureEvent = new MeasureEventArgs();
measureEvent.RulerTranslateUnit = measureInfo.RulerTranslateUnit;
measureEvent.RulerTranslate = measureInfo.RulerTranslate;
measureEvent.RulerBase = measureInfo.RulerBase;
measureEvent.RulerBaseUnit = measureInfo.RulerBaseUnit;
measureEvent.Precision = GetMeasureShowPrecision(measureInfo.Precision);
measureEvent.Type = CPDFMeasureType.CPDF_AREA_MEASURE;
NumberFormatInfo formatInfo = new NumberFormatInfo();
formatInfo.NumberDecimalDigits = Math.Abs(measureInfo.Precision).ToString().Length - 1;
measureEvent.Distance = currentInch.ToString("N", formatInfo) + " " + measureInfo.RulerTranslateUnit;
measureEvent.Area = inch.ToString("N", formatInfo) + " sq " + measureInfo.RulerTranslateUnit;
MeasureSetting.InvokeMeasureChangeEvent(this, measureEvent);
if (annotArgs != null)
{
SettingPanel.UpdateArgsList = new List { annotArgs };
}
}
}
catch (Exception e)
{
}
}
private double GetMeasureRatio(string baseUnit)
{
if (baseUnit == CPDFMeasure.CPDF_PT)
{
return 1 / 72;
}
if (baseUnit == CPDFMeasure.CPDF_IN)
{
return 1;
}
if (baseUnit == CPDFMeasure.CPDF_MM)
{
return 1 / 25.4;
}
if (baseUnit == CPDFMeasure.CPDF_CM)
{
return 1 / 2.54;
}
if (baseUnit == CPDFMeasure.CPDF_M)
{
return 1 / 0.0254;
}
if (baseUnit == CPDFMeasure.CPDFO_KM)
{
return 1 / 0.0254 / 1000;
}
if (baseUnit == CPDFMeasure.CPDF_FT)
{
return 12;
}
if (baseUnit == CPDFMeasure.CPDF_YD)
{
return 36;
}
if (baseUnit == CPDFMeasure.CPDF_MI)
{
return 63360;
}
return 0;
}
private double GetMeasureShowPrecision(int precision)
{
if (precision == CPDFMeasure.PRECISION_VALUE_ZERO)
{
return 1;
}
if (CPDFMeasure.PRECISION_VALUE_ONE == precision)
{
return 0.1;
}
if (CPDFMeasure.PRECISION_VALUE_TWO == precision)
{
return 0.01;
}
if (CPDFMeasure.PRECISION_VALUE_THREE == precision)
{
return 0.001;
}
if (CPDFMeasure.PRECISION_VALUE_FOUR == precision)
{
return 0.0001;
}
return 0;
}
public void SetSettingsControl(CPDFDisplaySettingsControl cPDFDisplaySettingsControl)
{
displaySettingsControl = cPDFDisplaySettingsControl;
}
public void ClearAllToolState()
{
PDFMeasureTool.ClearAllToolState();
}
public void ClearViewerControl()
{
PDFGrid.Child = null;
BotaContainer.Child = null;
PropertyContainer.Child = null;
displaySettingsControl = null;
}
private void PanelState_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(PanelState.IsLeftPanelExpand))
{
ExpandLeftPanel(panelState.IsLeftPanelExpand);
}
else if (e.PropertyName == nameof(PanelState.RightPanel))
{
if (panelState.RightPanel == PanelState.RightPanelState.PropertyPanel)
{
ExpandRightPropertyPanel(measurePropertyControl, Visibility.Visible);
}
else if (panelState.RightPanel == PanelState.RightPanelState.ViewSettings)
{
ExpandRightPropertyPanel(displaySettingsControl, Visibility.Visible);
}
else
{
ExpandRightPropertyPanel(null, Visibility.Collapsed);
}
}
}
#endregion
#region Expand and collapse Panel
public void ExpandRightPropertyPanel(Visibility visible)
{
ExpandRightPropertyPanel(measurePropertyControl, visible);
}
public void ExpandNullRightPropertyPanel(Visibility visible)
{
ExpandRightPropertyPanel(null, visible);
}
public void ExpandViewSettings(Visibility visible)
{
SetViewSettings(displaySettingsControl, visible);
}
private void ExpandRightPropertyPanel(UIElement propertytPanel, Visibility visible)
{
PropertyContainer.Width = 260;
PropertyContainer.Child = propertytPanel;
PropertyContainer.Visibility = visible;
}
private void SetViewSettings(CPDFDisplaySettingsControl displaySettingsControl, Visibility visibility)
{
PropertyContainer.Child = displaySettingsControl;
PropertyContainer.Visibility = visibility;
}
public void ExpandLeftPanel(bool isExpand)
{
BotaContainer.Visibility = isExpand ? Visibility.Visible : Visibility.Collapsed;
Splitter.Visibility = isExpand ? Visibility.Visible : Visibility.Collapsed;
if (isExpand)
{
BodyGrid.ColumnDefinitions[0].Width = new GridLength(320);
BodyGrid.ColumnDefinitions[1].Width = new GridLength(15);
}
else
{
BodyGrid.ColumnDefinitions[0].Width = new GridLength(0);
BodyGrid.ColumnDefinitions[1].Width = new GridLength(0);
}
}
#endregion
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
}
private void MeasureInfoPanel_SettingClick(object sender, EventArgs e)
{
if (sender is MeasureInfoPanel)
{
switch ((sender as MeasureInfoPanel).MeasureType)
{
case CPDFMeasureType.CPDF_DISTANCE_MEASURE:
case CPDFMeasureType.CPDF_PERIMETER_MEASURE:
SettingPanel.ShowAreaAndLength(Visibility.Collapsed);
break;
case CPDFMeasureType.CPDF_AREA_MEASURE:
SettingPanel.ShowAreaAndLength(Visibility.Visible);
break;
default:
break;
}
}
SettingPanel.ReturnToInfoPanel = true;
SetInfoPanelVisble(false, true);
SettingPanel.BindMeasureSetting();
}
private void SettingPanel_CancelEvent(object sender, EventArgs e)
{
SetInfoPanelVisble(SettingPanel.ReturnToInfoPanel, false);
}
private void SettingPanel_DoneEvent(object sender, EventArgs e)
{
SetInfoPanelVisble(SettingPanel.ReturnToInfoPanel, false);
}
public void SetInfoPanelVisble(bool measureInfo, bool measureSetting)
{
if (measureInfo)
{
InfoPanel.ClearMeasureInfo();
}
InfoPanel.Visibility = measureInfo ? Visibility.Visible : Visibility.Collapsed;
SettingPanel.Visibility = measureSetting ? Visibility.Visible : Visibility.Collapsed;
}
public void SetMeasureInfoType(CPDFMeasureType measureType)
{
InfoPanel?.SetMeasureType(measureType);
}
public void SetMeasureScale(CPDFMeasureType measureType, string scale)
{
InfoPanel?.SetMeasureScale(measureType,scale);
}
}
}