using Metis.Measuring; using PaintDotNet.Annotation.Enum; using PaintDotNet.Annotation.Measure; using PaintDotNet.Base.DedicatedAnalysis.Inclusions.Model; using PaintDotNet.SystemLayer; using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Drawing.Imaging; using System.Reflection; using System.Threading; using System.Windows.Forms; namespace PaintDotNet { /// /// 抽出来在各种弹窗里面使用 /// internal class DocumentWorkspaceWindow : DocumentView { private ZoomBasis zoomBasis; private ZoomBasis savedZb; private ScaleFactor savedSf; protected override void OnSizeChanged(EventArgs e) { PerformLayout(); base.OnSizeChanged(e); } protected override void OnLayout(LayoutEventArgs e) { if (this.zoomBasis == ZoomBasis.FitToWindow) { ZoomToWindow(); // This bizarre ordering of setting PanelAutoScroll prevents some very weird layout/scroll-without-scrollbars stuff. PanelAutoScroll = true; PanelAutoScroll = false; } base.OnLayout(e); } protected override void OnResize(EventArgs e) { if (this.zoomBasis == ZoomBasis.FitToWindow) { PerformLayout(); } base.OnResize(e); } public DocumentWorkspaceWindow(AppWorkspace appWorkspace) { this.AppWorkspaceTop = appWorkspace; this.InitToolsAndManager(); this.RulersEnabled = false; this.rightDown = false; InitializeComponent(); this.zoomBasis = ZoomBasis.FitToWindow; InitializeBottomEvent(); this.MouseEvent_Del(null, null); } public DocumentWorkspaceWindow() { this.RulersEnabled = false; this.rightDown = false; InitializeComponent(); this.zoomBasis = ZoomBasis.FitToWindow; InitializeBottomEvent(); this.MouseEvent_Del(null, null); } protected override void OnUnitsChanged() { base.OnUnitsChanged(); } private void InitializeComponent() { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } public override void ZoomIn() { this.ZoomBasis = ZoomBasis.ScaleFactor; base.ZoomIn(); } public override void ZoomIn(double factor) { this.ZoomBasis = ZoomBasis.ScaleFactor; base.ZoomIn(factor); } public override void ZoomOut() { this.ZoomBasis = ZoomBasis.ScaleFactor; base.ZoomOut(); } public override void ZoomOut(double factor) { this.ZoomBasis = ZoomBasis.ScaleFactor; base.ZoomOut(factor); } public event EventHandler ZoomBasisChanging; protected virtual void OnZoomBasisChanging() { if (ZoomBasisChanging != null) { ZoomBasisChanging(this, EventArgs.Empty); } } public event EventHandler ZoomBasisChanged; protected virtual void OnZoomBasisChanged() { if (ZoomBasisChanged != null) { ZoomBasisChanged(this, EventArgs.Empty); } } public ZoomBasis ZoomBasis { get { return this.zoomBasis; } set { if (this.zoomBasis != value) { OnZoomBasisChanging(); this.zoomBasis = value; switch (this.zoomBasis) { case ZoomBasis.FitToWindow: ZoomToWindow(); // Enable PanelAutoScroll only long enough to recenter the view PanelAutoScroll = true; PanelAutoScroll = false; // this would be unset by the scalefactor changes in ZoomToWindow this.zoomBasis = ZoomBasis.FitToWindow; break; case ZoomBasis.ScaleFactor: PanelAutoScroll = true; break; default: throw new InvalidEnumArgumentException(); } OnZoomBasisChanged(); } } } protected override void HandleMouseWheel(Control sender, MouseEventArgs e) { if (Control.ModifierKeys == Keys.Control && !disableWheel) { double mouseDelta = (double)e.Delta / 120.0f; Rectangle visibleDocBoundsStart = this.VisibleDocumentBounds; System.Drawing.Point mouseDocPt = this.MouseToDocument(sender, new System.Drawing.Point(e.X, e.Y)); RectangleF visibleDocDocRect1 = this.VisibleDocumentRectangleF; PointF mouseNPt = new PointF( (mouseDocPt.X - visibleDocDocRect1.X) / visibleDocDocRect1.Width, (mouseDocPt.Y - visibleDocDocRect1.Y) / visibleDocDocRect1.Height); Rectangle rc = this.PanelClientRectangle; int width = this.SurfaceScrollableWidth; int height = this.SurfaceScrollableHeight; //获取鼠标在图像中的坐标定位 double originX = 0.5; double originY = 0.5; double ptxInDoc = mouseDocPt.X * this.ScaleRatio; double ptyInDoc = mouseDocPt.Y * this.ScaleRatio; if (rc.Width < width) { originX = (ptxInDoc + this.PanelScrollPosition.X - 0.0) / width; } if (rc.Height < height) { originY = (ptyInDoc + this.PanelScrollPosition.Y - 0.0) / height; } const double factor = 1.12; double mouseFactor = Math.Pow(factor, Math.Abs(mouseDelta)); if (e.Delta > 0) { this.ZoomIn(mouseFactor); } else if (e.Delta < 0) { this.ZoomOut(mouseFactor); } RectangleF visibleDocDocRect2 = this.VisibleDocumentRectangleF; PointF scrollPt2 = new PointF( mouseDocPt.X - visibleDocDocRect2.Width * mouseNPt.X, mouseDocPt.Y - visibleDocDocRect2.Height * mouseNPt.Y); this.DocumentScrollPositionF = scrollPt2; int width2 = this.SurfaceScrollableWidth; int height2 = this.SurfaceScrollableHeight; if ((rc.Width < width2 || rc.Height < height2) && (rc.Width < width || rc.Height < height)) { //根据鼠标在图像中的坐标重新定位放大后的图像 this.PanelScrollPosition = new System.Drawing.Point( (int)(width2 * originX - ptxInDoc + 0), (int)(height2 * originY - ptyInDoc + 0)); } else if (rc.Width < width2 || rc.Height < height2) { this.PanelScrollPosition = new System.Drawing.Point((int)(width2 - rc.Width) / 2 + 0, (int)(height2 - rc.Height) / 2 + 0); } else { this.PanelScrollPosition = new System.Drawing.Point((int)(width2 - rc.Width) / 2 + 0, (int)(height2 - rc.Height) / 2 + 0); } Rectangle visibleDocBoundsEnd = this.VisibleDocumentBounds; if (visibleDocBoundsEnd != visibleDocBoundsStart) { // Make sure the screen updates, otherwise it can get a little funky looking this.Update(); } } base.HandleMouseWheel(sender, e); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); } public event EventHandler ActiveLayerChanged; protected void OnLayerChanged() { this.Focus(); if (ActiveLayerChanged != null) { ActiveLayerChanged(this, EventArgs.Empty); } } /// /// 初始化底部按钮的各种事件 /// private void InitializeBottomEvent() { /*//缩小按钮 this.PanelBottom.zoomOutButton.Click += new EventHandler(ZoomOutButton_Click); //放大按钮 this.PanelBottom.zoomInButton.Click += new EventHandler(zoomInButton_Click);*/ } private void ZoomOutButton_Click(object sender, EventArgs e) { this.ZoomOut(); } private void zoomInButton_Click(object sender, EventArgs e) { this.ZoomIn(); } public event EventHandler ToolChanging; protected void OnToolChanging() { if (ToolChanging != null) { ToolChanging(this, EventArgs.Empty); } } public event EventHandler ToolChanged; protected void OnToolChanged() { if (ToolChanged != null) { ToolChanged(this, EventArgs.Empty); } } /// /// Updates any pertinent EXIF tags, such as "Creation Software", to be /// relevant or up-to-date. /// /// private void UpdateExifTags(Document document) { PropertyItem pi = Exif.CreateAscii(ExifTagID.Software, PdnInfo.GetProductName(false)); document.Metadata.ReplaceExifValues(ExifTagID.Software, new PropertyItem[1] { pi }); } public void SetInclusion(Inclusion Inclusion) { this.inclusion = Inclusion; } protected override void OnDocumentChanging(Document newDocument) { base.OnDocumentChanging(newDocument); this.savedZb = this.ZoomBasis; this.savedSf = ScaleFactor; if (newDocument != null) { UpdateExifTags(newDocument); } } protected override void OnDocumentChanged() { bool oldDirty = this.Document.Dirty; this.Document.Invalidate(); this.Document.Dirty = oldDirty; this.ZoomBasis = this.savedZb; if (this.savedZb == ZoomBasis.ScaleFactor) { ScaleFactor = this.savedSf; } AutoScrollPosition = new Point(0, 0); base.OnDocumentChanged(); } private sealed class OurProgressEvents : IFileTransferProgressEvents { private TransferProgressDialog progressDialog; private ICancelable cancelSink; private int itemCount = 0; private int itemOrdinal = 0; private string itemName = string.Empty; private long totalWork; private long totalProgress; private const int maxPBValue = 200; // granularity of progress bar. 100 means 1%, 200 means 0.5%, etc. private bool cancelRequested = false; private ManualResetEvent operationEnded = new ManualResetEvent(false); public OurProgressEvents() { } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "cancelSink")] public void BeginOperation(IWin32Window owner, EventHandler callWhenUIShown, ICancelable cancelSink) { if (this.progressDialog != null) { throw new InvalidOperationException("Operation already in progress"); } this.progressDialog = new TransferProgressDialog(); this.progressDialog.Text = PdnResources.GetString("ShowFileDialog.TransferProgress.Title"); this.progressDialog.Icon = Utility.ImageToIcon(PdnResources.GetImageResource("Icons.MenuFileOpenIcon.png").Reference); this.progressDialog.Title = PdnResources.GetString("ShowFileDialog.ItemText.Initializing"); this.progressDialog.ProgressBar.Style = ProgressBarStyle.Marquee; this.progressDialog.ProgressBar.Maximum = maxPBValue; this.progressDialog.CancelClicked += delegate (object sender, EventArgs e) { this.cancelRequested = true; this.cancelSink.RequestCancel(); UpdateUI(); }; EventHandler progressDialog_Shown = delegate (object sender, EventArgs e) { callWhenUIShown(this, EventArgs.Empty); }; this.cancelSink = cancelSink; this.itemOrdinal = 0; this.cancelRequested = false; this.itemName = string.Empty; this.itemCount = 0; this.itemOrdinal = 0; this.totalProgress = 0; this.totalWork = 0; this.progressDialog.Shown += progressDialog_Shown; this.progressDialog.ShowDialog(owner); this.progressDialog.Shown -= progressDialog_Shown; this.progressDialog.Dispose(); this.progressDialog = null; this.cancelSink = null; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "itemCount")] public void SetItemCount(int itemCount) { if (this.progressDialog.InvokeRequired) { this.progressDialog.BeginInvoke(new Procedure(SetItemCount), new object[] { itemCount }); } else { this.itemCount = itemCount; UpdateUI(); } } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "itemOrdinal")] public void SetItemOrdinal(int itemOrdinal) { if (this.progressDialog.InvokeRequired) { this.progressDialog.BeginInvoke(new Procedure(SetItemOrdinal), new object[] { itemOrdinal }); } else { this.itemOrdinal = itemOrdinal; this.totalWork = 0; this.totalProgress = 0; UpdateUI(); } } public void SetItemInfo(string itemInfo) { if (this.progressDialog.InvokeRequired) { this.progressDialog.BeginInvoke(new Procedure(SetItemInfo), new object[] { itemInfo }); } else { this.itemName = itemInfo; UpdateUI(); } } public void BeginItem() { if (this.progressDialog.InvokeRequired) { this.progressDialog.BeginInvoke(new Procedure(BeginItem), null); } else { this.progressDialog.ProgressBar.Style = ProgressBarStyle.Continuous; } } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "totalWork")] public void SetItemWorkTotal(long totalWork) { if (this.progressDialog.InvokeRequired) { this.progressDialog.BeginInvoke(new Procedure(SetItemWorkTotal), new object[] { totalWork }); } else { this.totalWork = totalWork; UpdateUI(); } } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "totalProgress")] public void SetItemWorkProgress(long totalProgress) { if (this.progressDialog.InvokeRequired) { this.progressDialog.BeginInvoke(new Procedure(SetItemWorkProgress), new object[] { totalProgress }); } else { this.totalProgress = totalProgress; UpdateUI(); } } public void EndItem(WorkItemResult result) { if (this.progressDialog.InvokeRequired) { this.progressDialog.BeginInvoke(new Procedure(EndItem), new object[] { result }); } else { } } public void EndOperation(OperationResult result) { if (this.progressDialog.InvokeRequired) { this.progressDialog.BeginInvoke(new Procedure(EndOperation), new object[] { result }); } else { this.progressDialog.Close(); } } public WorkItemFailureAction ReportItemFailure(Exception ex) { if (this.progressDialog.InvokeRequired) { object result = this.progressDialog.Invoke( new Function(ReportItemFailure), new object[] { ex }); return (WorkItemFailureAction)result; } else { WorkItemFailureAction result; result = ShowFileTransferFailedDialog(ex); return result; } } private WorkItemFailureAction ShowFileTransferFailedDialog(Exception ex) { WorkItemFailureAction result; Icon formIcon = this.progressDialog.Icon; string formTitle = PdnResources.GetString("ShowFileDialog.ItemFailureDialog.Title"); Image taskImage = PdnResources.GetImageResource("Icons.WarningIcon.png").Reference; string introTextFormat = PdnResources.GetString("ShowFileDialog.ItemFailureDialog.IntroText.Format"); string introText = string.Format(introTextFormat, ex.Message); TaskButton retryTB = new TaskButton( PdnResources.GetImageResource("Icons.MenuImageRotate90CWIcon.png").Reference, PdnResources.GetString("ShowFileDialog.RetryTB.ActionText"), PdnResources.GetString("ShowFileDialog.RetryTB.ExplanationText")); TaskButton skipTB = new TaskButton( PdnResources.GetImageResource("Icons.HistoryFastForwardIcon.png").Reference, PdnResources.GetString("ShowFileDialog.SkipTB.ActionText"), PdnResources.GetString("ShowFileDialog.SkipTB.ExplanationText")); TaskButton cancelTB = new TaskButton( PdnResources.GetImageResource("Icons.CancelIcon.png").Reference, PdnResources.GetString("ShowFileDialog.CancelTB.ActionText"), PdnResources.GetString("ShowFileDialog.CancelTB.ExplanationText")); List taskButtons = new List(); taskButtons.Add(retryTB); // Only have the Skip button if there is more than 1 item being transferred. // If only 1 item is begin transferred, Skip and Cancel are essentially synonymous. if (this.itemCount > 1) { taskButtons.Add(skipTB); } taskButtons.Add(cancelTB); int width96 = (TaskDialog.DefaultPixelWidth96Dpi * 4) / 3; // 33% wider TaskButton clickedTB = TaskDialog.Show( this.progressDialog, formIcon, formTitle, taskImage, true, introText, taskButtons.ToArray(), retryTB, cancelTB, width96, false, 0, out bool unuse); if (clickedTB == retryTB) { result = WorkItemFailureAction.RetryItem; } else if (clickedTB == skipTB) { result = WorkItemFailureAction.SkipItem; } else { result = WorkItemFailureAction.CancelOperation; } return result; } private void UpdateUI() { int itemCount2 = Math.Max(1, this.itemCount); double startValue = (double)this.itemOrdinal / (double)itemCount2; double endValue = (double)(this.itemOrdinal + 1) / (double)itemCount2; long totalWork2 = Math.Max(1, this.totalWork); double lerp = (double)this.totalProgress / (double)totalWork2; double newValue = Utility.Lerp(startValue, endValue, lerp); int newValueInt = (int)Math.Ceiling(maxPBValue * newValue); if (this.cancelRequested) { this.progressDialog.CancelEnabled = false; this.progressDialog.Title = PdnResources.GetString("ShowFileDialog.ItemText.Canceling"); this.progressDialog.ProcessMsg = string.Empty; this.progressDialog.ProgressBar.Style = ProgressBarStyle.Marquee; } else { this.progressDialog.CancelEnabled = true; this.progressDialog.Title = this.itemName; string progressFormat = PdnResources.GetString("ShowFileDialog.ProgressText.Format"); string progressText = string.Format(progressFormat, this.itemOrdinal + 1, this.itemCount); this.progressDialog.ProcessMsg = progressText; this.progressDialog.ProgressBar.Style = ProgressBarStyle.Continuous; this.progressDialog.ProgressBar.Value = newValueInt; } } } /// /// 更新测量单位,刷新UI /// /// public void UpdateMeasureUnit(MeasurementUnit measurementUnit) { //循环所有测量,更新单位 if (this.GraphicsList != null && this.GraphicsList.Count > 0) { int count = this.GraphicsList.Count; for (int i = 0; i < count; i++) { if (this.GraphicsList[i].objectType == DrawClass.Measure) { ((MeasureDrawObject)(this.GraphicsList[i])).MeasurementUnit = measurementUnit; } } } this.Refresh(); } /// /// 分栏显示禁止滚动改变图片大小 /// bool disableWheel = false; public void removeEvent() { disableWheel = true; } DateTime _time; protected override void MouseEvent_Move(object sender, MouseEventArgs e) { if (this.AppWorkspaceTop != null && this.compositionSurface != null && this.pixelTrackingEnabled) //&& e.Location.X>=0 && e.Location.Y>=0 //&& e.Location.X<=this.Surface.Width //&& e.Location.Y <= this.Surface.Height) { if ((DateTime.Now - _time).TotalMilliseconds > 20) { //this.AppWorkspaceTop.SetImageAndData(this.ScaleFactor.UnscalePoint(e.Location)); (this.AppWorkspaceTop as AppWorkspace).SetImageAndData(this.CalcPixelPoint(e.Location), this); _time = DateTime.Now; base.MouseEvent_Move(sender, e); } } } protected override void MouseEvent_Down(object sender, MouseEventArgs e) { if (tools != null) { //tools[activeTool].OnMouseDown(this, e); tools[_activeTool].InvokeMember("OnMouseDown", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[2] { this, e }); } RefreshDrawNodes(); if (e.Button == MouseButtons.Right) { ShowContextMenuStrip1(); } } public void RefreshDrawNodes() { TreeView drawTreeView = this.oldDrawTreeView; if (drawTreeView != null) { for (int i = 0; i < this.GraphicsList.Count; i++) { if (this.GraphicsList[i].objectType == DrawClass.Measure) { int count1 = drawTreeView.Nodes.Count; ((MeasureDrawObject)(this.GraphicsList[i])).drawingProperties.Clear(); ((MeasureDrawObject)(this.GraphicsList[i])).pointChangeObject.Clear(); for (int k = 0; k < count1; k++) { int count2 = drawTreeView.Nodes[k].Nodes.Count; for (int j = 0; j < count2; j++) { if (this.GraphicsList[i].drawToolType == (DrawToolType)Enum.Parse(typeof(DrawToolType), drawTreeView.Nodes[k].Nodes[j].Name)) { bool drawb = false; if (drawTreeView.Nodes[k].Nodes[j].Nodes.Count == 0) { ((MeasureDrawObject)(this.GraphicsList[i])).drawingProperties.Add((DrawToolType)Enum.Parse(typeof(DrawToolType), drawTreeView.Nodes[k].Nodes[j].Name), new string[] { "nothing" }); if (this.oldDrawTreeView != null) { if (this.oldDrawTreeView.Nodes[k].Nodes[j].Nodes.Count != 0) ((MeasureDrawObject)(this.GraphicsList[i])).pointChangeObject.Add((DrawToolType)Enum.Parse(typeof(DrawToolType), drawTreeView.Nodes[k].Nodes[j].Name), true); } else { ((MeasureDrawObject)(this.GraphicsList[i])).pointChangeObject.Add((DrawToolType)Enum.Parse(typeof(DrawToolType), drawTreeView.Nodes[k].Nodes[j].Name), true); } } else { int a = 0; string[] arr = new string[drawTreeView.Nodes[k].Nodes[j].Nodes.Count]; foreach (TreeNode node2 in drawTreeView.Nodes[k].Nodes[j].Nodes) { arr[a] = node2.Name; a++; } ((MeasureDrawObject)(this.GraphicsList[i])).drawingProperties.Add((DrawToolType)Enum.Parse(typeof(DrawToolType), drawTreeView.Nodes[k].Nodes[j].Name), arr); if (this.oldDrawTreeView != null) { if (drawTreeView.Nodes[k].Nodes[j].Nodes.Count != this.oldDrawTreeView.Nodes[k].Nodes[j].Nodes.Count) { ((MeasureDrawObject)(this.GraphicsList[i])).pointChangeObject.Add((DrawToolType)Enum.Parse(typeof(DrawToolType), drawTreeView.Nodes[k].Nodes[j].Name), true); } else { foreach (TreeNode oldNode in this.oldDrawTreeView.Nodes[k].Nodes[j].Nodes) { /*if (!arr.Contains(oldNode.Name)) { drawb = true; }*/ } if (drawb) ((MeasureDrawObject)(this.GraphicsList[i])).pointChangeObject.Add((DrawToolType)Enum.Parse(typeof(DrawToolType), drawTreeView.Nodes[k].Nodes[j].Name), drawb); } } else { ((MeasureDrawObject)(this.GraphicsList[i])).pointChangeObject.Add((DrawToolType)Enum.Parse(typeof(DrawToolType), drawTreeView.Nodes[k].Nodes[j].Name), true); } } } } } } } this.Refresh(); } } public override void ShowContextMenuStrip1() { if (toolNumber == 1) { contextMenuStrip1.Visible = true; toolStripMenuItem1.Visible = false; toolStripMenuItem2.Visible = false; toolStripMenuItem3.Visible = true; toolStripMenuItem4.Visible = false; } else { toolStripMenuItem1.Visible = false; toolStripMenuItem2.Visible = false; toolStripMenuItem3.Visible = false; toolStripMenuItem4.Visible = false; } } public override void ToolStripMenuItem3_Click(object sender, EventArgs e) { for (int i = 0; i < this.GraphicsList.Count; i++) { if (GraphicsList[i].Selected) { MeasurementPropertiesDialog measurementPropertiesDialog = new MeasurementPropertiesDialog(AppWorkspaceTop as AppWorkspace, this.GraphicsList[i]); measurementPropertiesDialog.StartPosition = FormStartPosition.CenterScreen; measurementPropertiesDialog.ShowDialog(); this.Refresh(); } } } } }