using PaintDotNet.SystemLayer;
using System;
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 DocumentStitchWindow : DocumentStitchView
{
private ZoomBasis zoomBasis;
protected override void OnLayout(LayoutEventArgs e)
{
if (this.zoomBasis == ZoomBasis.FitToWindow)
{
ZoomToPreviewWindow();
// 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 DocumentStitchWindow()
{
this.InitToolsAndManager();
InitializeComponent();
this.zoomBasis = ZoomBasis.FitToWindow;
InitializeBottomEvent();
this.MouseEvent_Del(null, null);
}
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 int OffsetH
//{
// set
// {
// this.panel.AutoScrollPosition.X = value;
// }
//}
///
/// 持有mat的有效区域
///
public OpenCvSharp.Mat StitchMat
{
get
{
if (this.StitchDocument == null || this.StitchDocument.surface == null) return null;
return this.StitchDocument.surface.StitchMat;
}
}
///
/// 持有mat的绘制区域
///
public Rectangle StitchBounds
{
get
{
return this.StitchDocument.surface.stitchBounds;
}
set
{
this.StitchDocument.surface.stitchBounds = value;
}
}
///
/// 持有mat的绘制区域
///
public int StitchWidth
{
get
{
return this.StitchDocument.surface.StitchWidth;
}
}
///
/// 持有mat的绘制区域
///
public int StitchHeight
{
get
{
return this.StitchDocument.surface.StitchHeight;
}
}
///
/// 合适大小
///
public void ZoomToPreviewWindow()
{
if (this.StitchDocument != null)
{
Rectangle max = ClientRectangleMax;
ScaleFactor zoom = ScaleFactor.Min(max.Width - 10,
this.StitchBounds.Width,
max.Height - 10,
this.StitchBounds.Height,
ScaleFactor.MinValue);
ScaleFactor min = ScaleFactor.Min(zoom, ScaleFactor.OneToOne);
this.ScaleFactor = min;
}
}
public ZoomBasis ZoomBasis
{
get
{
return this.zoomBasis;
}
set
{
if (this.zoomBasis != value)
{
OnZoomBasisChanging();
this.zoomBasis = value;
//this.panel.AutoScrollOffset
switch (this.zoomBasis)
{
case ZoomBasis.FitToWindow:
ZoomToPreviewWindow();
//// 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 && this.compositionSurface != null)
{
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(StitchDocument document)
{
PropertyItem pi = Exif.CreateAscii(ExifTagID.Software, PdnInfo.GetProductName(false));
document.Metadata.ReplaceExifValues(ExifTagID.Software, new PropertyItem[1] { pi });
}
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;
}
}
}
///
/// 分栏显示禁止滚动改变图片大小
///
bool disableWheel = false;
DateTime _time;
protected override void MouseEvent_Move(object sender, MouseEventArgs e)
{
if (this.compositionSurface != null)
{
if ((DateTime.Now - _time).TotalMilliseconds > 20)
{
_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 });
}
}
}
}