using DevExpress.XtraEditors.Repository;
using DevExpress.XtraVerticalGrid.Rows;
using GeoSigmaDrawLib;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
//using Dector = OutlineDetectionUtil;
namespace RiverPortray
{
///
/// 河道刻画主窗体.
///
public partial class FormMain : DevExpress.XtraEditors.XtraForm
{
///
/// 模块进程名称
///
public static string ProcessName { get; set; } = "轮廓刻画";
public EventHandler PushDataClick;
private IntPtr pXy = IntPtr.Zero;
private bool isSyncing = false; // 用于防止事件循环
private bool isUserClick = true;
private double GridZMin = 0;
private double GridZMax = 100;
///
/// Initializes a new instance of the class.
///
public FormMain()
{
InitializeComponent();
this.Text = ProcessName;
// Initialize the Qt Application (do not use DllMain for this)
OutlineDetector.InitializeQtApplication();
IntPtr hWin = pcbView.Handle;
OutlineDetector.EmbedQtWidget(hWin);
}
///
/// Initializes a new instance of the class.
///
/// The p xy.
public FormMain(IntPtr pXy)
: this()
{
this.pXy = pXy;
}
///
/// 窗体加载事件.
///
/// The sender.
/// The e.
private void FormMain_Load(object sender, EventArgs e)
{
if(this.pXy != IntPtr.Zero)
{
double dXMin = 0;
double dYMin = 0;
double dStepX = 0;
double dStepY = 0;
double dZMin = 0;
double dZMax = 0;
int nNumX = 0;
int nNumY = 0;
long lpValue = 0;
bool bSuccess = DrawerData.XyGetMeshData(this.pXy, ref dXMin, ref dYMin, ref nNumX, ref nNumY, ref dStepX, ref dStepY, ref lpValue, ref dZMin, ref dZMax);
if (bSuccess)
{
OutlineDetector.LoadGrid(nNumX, nNumY, dXMin, dYMin, dStepX, dStepY, lpValue, dZMin, dZMax);
this.loadParameters();
}
}
}
///
/// 窗体关闭事件.
///
/// The e.
protected override void OnFormClosed(FormClosedEventArgs e)
{
// Clean up Qt Application when the WinForms application closes
OutlineDetector.ShutdownQtApplication();
base.OnFormClosed(e);
}
///
/// 打开文件事件.
///
/// The sender.
/// The e.
private void bbtnOpenFile_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "*.dfg|*.dfg|*.keg|*.keg|*.*|*.*";
ofd.RestoreDirectory = true;
if(ofd.ShowDialog() == DialogResult.OK)
{
string strFile = ofd.FileName;
bool bResult = OutlineDetector.LoadGridFile(strFile);
if(bResult == true)
{
loadParameters();
}
}
}
///
/// 加载参数信息.
///
private void loadParameters()
{
isUserClick = false;
if (this.bbtnViewColorful.Down == false)
{
this.bbtnViewColorful.Down = true;
}
FaciesParameter par = this.GetFaciesParameter();
this.BindCaculatePara(par);
GridParameter grdPar = GetGridParameter();
this.propertyGridControl1.SelectedObject = grdPar;
isUserClick = true;
}
///
/// 绑定计算参数.
///
/// The par.
private void BindCaculatePara(FaciesParameter par)
{
isSyncing = true;
this.txtZMin.Text = $"{par.ZMin:F4}";
this.txtZMax.Text = $"{par.ZMax:F4}";
double dZMin = 0;
double dZMax = 0;
if (OutlineDetector.GetSurfaceZRange(ref dZMin, ref dZMax))
{
this.GridZMin = dZMin;
this.GridZMax = dZMax;
trackZMin.Properties.Minimum = 0; // (int)dZMin;
trackZMin.Properties.Maximum = 100;// (int)dZMax;
trackZMin.Value = (int)((par.ZMin- this.GridZMin) / (this.GridZMax- this.GridZMin)*100);
trackZMax.Properties.Minimum = 0;
trackZMax.Properties.Maximum = 100;
trackZMax.Value = (int)((par.ZMax - this.GridZMin) / (this.GridZMax - this.GridZMin) * 100);
}
int dDialatMax = 0;
if (OutlineDetector.GetDilateMax(ref dDialatMax))
{
this.speDilate.Properties.MinValue = 0;
this.speDilate.Properties.MaxValue = dDialatMax;
this.speDilate.Value = 2;
}
this.txtAreaMin.Text = $"{par.AreaMin}";
this.txtSmoothTimes.Text = $"{par.SmoothTimes}";
isSyncing = false;
}
///
/// 窗体尺寸变化事件
///
/// The sender.
/// The e.
private void pcbView_SizeChanged(object sender, EventArgs e)
{
// Resize the Qt widget to match the size of the panel
OutlineDetector.ResizeQtWidget(pcbView.Width, pcbView.Height);
}
///
/// 原图按钮点击事件.
///
/// The sender.
/// The e.
private void bbtnViewColorful_DownChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
if (bbtnViewColorful.Down && isUserClick == true)
{
OutlineDetector.ViewColorful();
}
this.bbtnPushBack.Enabled = bbtnCreateLines.Down;
this.bbtnExportLines.Enabled = this.bbtnPushBack.Enabled;
}
///
/// 黑白图按钮点击事件.
///
/// The sender.
/// The e.
private void bbtnViewBlackWhite_DownChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
this.ViewInBlackBlack();
this.bbtnPushBack.Enabled = bbtnCreateLines.Down;
this.bbtnExportLines.Enabled = this.bbtnPushBack.Enabled;
}
///
/// Views the in black black.
///
private void ViewInBlackBlack()
{
if (bbtnViewBlackWhite.Down)
{
OutlineDetector.ViewBlackWhite();
}
}
///
/// 生成轮廓线.
///
private void ReCreateLines()
{
if (this.bbtnCreateLines.Down)
{
OutlineDetector.CreateLines();
}
}
///
/// 生成刻画线事件.
///
/// The sender.
/// The e.
private void bbtnCreateLines_DownChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
ReCreateLines();
this.bbtnPushBack.Enabled = bbtnCreateLines.Down;
this.bbtnExportLines.Enabled = this.bbtnPushBack.Enabled;
}
///
/// Gets the 刻画参数信息.
///
/// A FaciesParameter.
private FaciesParameter GetFaciesParameter()
{
FaciesParameter par = new FaciesParameter();
par.ZMin= OutlineDetector.GetFaciesZMin();
par.ZMax = OutlineDetector.GetFaciesZMax();
par.Dilate = OutlineDetector.GetDilate();
par.AreaMin = OutlineDetector.GetFaciesAreaMin();
par.SmoothTimes = OutlineDetector.GetFaciesSmoothTimes();
return par;
}
///
/// 获取网格信息.
///
/// A GridParameter.
private GridParameter GetGridParameter()
{
GridParameter par = new GridParameter();
int xNum = 0;
int yNum = 0;
double deltaX = 0;
double deltaY = 0;
double zMin = 0;
double zMax = 0;
OutlineDetector.GetSurfaceParameter(ref xNum, ref yNum, ref deltaX, ref deltaY, ref zMin, ref zMax);
par.XNum = xNum;
par.YNum = yNum;
par.DeltX = deltaX;
par.DeltY = deltaY;
par.ZMin = zMin;
par.ZMax = zMax;
return par;
}
///
/// properties the grid control1_ custom row created.
///
/// The sender.
/// The e.
private void propertyGridControl1_CustomRowCreated(object sender, DevExpress.XtraVerticalGrid.Events.CustomRowCreatedEventArgs e)
{
if(e.Row is PGridNumericEditorRow numRow)
{
// 创建并配置 RepositoryItemTextEdit
RepositoryItemTextEdit textEdit = new RepositoryItemTextEdit();
textEdit.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric;
textEdit.DisplayFormat.FormatString = "F2"; // 保留两位小数,"F3" 表示保留三位小数
textEdit.EditFormat.FormatType = DevExpress.Utils.FormatType.Numeric;
textEdit.EditFormat.FormatString = "F2"; // 编辑时保留两位小数
// 将 RepositoryItemTextEdit 赋给该行
numRow.Properties.RowEdit = textEdit;
}
//if (e.Row.Properties.FieldName == "ZMin"
// || e.Row.Properties.FieldName == "ZMax")
//{
// SetupRowZ(e.Row as PGridNumericEditorRow);
//}
//else if (e.Row.Properties.FieldName == "Dilate")
//{
// int dDialatMax = 0;
// if (OutlineDetector.GetDilateMax(ref dDialatMax))
// {
// ((PGridNumericEditorRow)e.Row).MaxValue = dDialatMax;
// }
//}
}
///
/// Setups the row z.
///
/// The row.
protected void SetupRowZ(PGridNumericEditorRow row)
{
double dZMin = 0;
double dZMax = 0;
if (OutlineDetector.GetSurfaceZRange(ref dZMin, ref dZMax))
{
row.MinValue = -(int)dZMax;
row.MaxValue = -(int)dZMin;
//// 显式创建并设置 SpinEdit 编辑器
//RepositoryItemSpinEdit spinEdit = new RepositoryItemSpinEdit
//{
// MinValue = (decimal)dZMin,
// MaxValue = (decimal)dZMax
//};
// 显式创建并设置 TrackBar 编辑器
RepositoryItemTrackBar trackBarEdit = new RepositoryItemTrackBar
{
Minimum = (int)dZMin, // TrackBar 只能接受整数
Maximum = (int)dZMax // 设置负数范围的最大值
};
// 将自定义的 SpinEdit 分配给行
row.Properties.RowEdit = trackBarEdit;
row.ShowTrackBar = true;
}
}
public class FixPGridNumericEditorRow: PGridNumericEditorRow
{
public FixPGridNumericEditorRow() : base()
{
}
protected override Size CalcEditorSize()
{
if (!ShowTrackBar)
{
return base.CalcEditorSize();
}
int nWidth = Math.Max(60, base.Grid.ViewInfo.ViewRects.ScrollableRectangle.Width / 5);
return new Size(nWidth, base.Grid.OptionsView.MinRowAutoHeight);
}
}
///
/// properties the grid control1_ custom property descriptors.
///
/// The sender.
/// The e.
private void propertyGridControl1_CustomPropertyDescriptors(object sender, DevExpress.XtraVerticalGrid.Events.CustomPropertyDescriptorsEventArgs e)
{
e.Properties = e.Properties.Sort(new string[] { "ZMin", "ZMax", "Dilate", "AreaMin", "SmoothTimes" });
}
///
/// txts the z min_ edit value changed.
///
/// The sender.
/// The e.
private void txtZMin_EditValueChanged(object sender, EventArgs e)
{
if(isSyncing == false)
{
isSyncing = true;// 防止事件循环
double newValue;
if (double.TryParse(txtZMin.Text, out newValue))
{
// 设置 TrackBarControl 的值,且值必须在其范围内
if (newValue >= this.GridZMin && newValue <= this.GridZMax)
{
trackZMin.Value = (int)((newValue-this.GridZMin)/(this.GridZMax-this.GridZMin)*100);
OutlineDetector.SetFaciesZMin(newValue);
// 重新生成轮廓
ReCreateLines();
ViewInBlackBlack();
}
}
isSyncing = false;
}
}
///
/// tracks the z min_ edit value changed.
///
/// The sender.
/// The e.
private void trackZMin_EditValueChanged(object sender, EventArgs e)
{
if (!isSyncing)
{
isSyncing = true; // 防止事件循环
double zValue = (trackZMin.Value / 100.0) * (this.GridZMax - this.GridZMin) + this.GridZMin;
txtZMin.Text = zValue.ToString("F4");
OutlineDetector.SetFaciesZMin(zValue);
// 重新生成轮廓
ReCreateLines();
ViewInBlackBlack();
isSyncing = false;
}
}
///
/// txts the z max_ edit value changed.
///
/// The sender.
/// The e.
private void txtZMax_EditValueChanged(object sender, EventArgs e)
{
if (isSyncing == false)
{
isSyncing = true;// 防止事件循环
double newValue;
if (double.TryParse(txtZMax.Text, out newValue))
{
// 设置 TrackBarControl 的值,且值必须在其范围内
if (newValue >= this.GridZMin && newValue <= this.GridZMax)
{
trackZMax.Value = (int)((newValue - this.GridZMin) / (this.GridZMax - this.GridZMin) * 100);
OutlineDetector.SetFaciesZMax(newValue);
this.ReCreateLines();
this.ViewInBlackBlack();
}
}
isSyncing = false;
}
}
///
/// tracks the z max_ edit value changed.
///
/// The sender.
/// The e.
private void trackZMax_EditValueChanged(object sender, EventArgs e)
{
if (!isSyncing)
{
isSyncing = true; // 防止事件循环
double zValue = (trackZMax.Value / 100.0) * (this.GridZMax - this.GridZMin) + this.GridZMin;
txtZMax.Text = zValue.ToString("F4");
OutlineDetector.SetFaciesZMax(zValue);
this.ReCreateLines();
this.ViewInBlackBlack();
isSyncing = false;
}
}
///
/// 膨胀系数数据变化事件.
///
/// The sender.
/// The e.
private void speDilate_EditValueChanged(object sender, EventArgs e)
{
OutlineDetector.SetDilate((int)speDilate.Value);
this.ReCreateLines();
}
///
/// 最小面积修改事件.
///
/// The sender.
/// The e.
private void txtAreaMin_EditValueChanged(object sender, EventArgs e)
{
double newValue;
if (double.TryParse(txtAreaMin.Text, out newValue))
{
OutlineDetector.SetFaciesAreaMin(newValue);
this.ReCreateLines();
}
}
///
/// 平滑次数修改事件.
///
/// The sender.
/// The e.
private void txtSmoothTimes_EditValueChanged(object sender, EventArgs e)
{
int newValue;
if (int.TryParse(txtSmoothTimes.Text, out newValue))
{
OutlineDetector.SetFaciesSmoothTimes(newValue);
this.ReCreateLines();
}
}
private void propertyGridControl1_CustomRecordCellEdit(object sender, DevExpress.XtraVerticalGrid.Events.GetCustomRowCellEditEventArgs e)
{
//var editor = e.RepositoryItem;
//if(editor is RepositoryItemTextEdit textEdit)
//{
// textEdit.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric;
// textEdit.DisplayFormat.FormatString = "F2";
// textEdit.EditFormat.FormatType = DevExpress.Utils.FormatType.Numeric;
// textEdit.EditFormat.FormatString = "F2"; // 编辑时保留两位小数
//}
}
///
/// 导出轮廓线数据.
///
/// The sender.
/// The e.
private void bbtnExportLines_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
SaveFileDialog ofd = new SaveFileDialog();
ofd.Filter = "*.kev|*.kev";
ofd.RestoreDirectory = true;
ofd.OverwritePrompt = true;
if (ofd.ShowDialog() == DialogResult.OK)
{
// 调用C++函数获取字符串
IntPtr messagePtr = OutlineDetector.GetContourData();
// 将IntPtr转换为C#的字符串
string message = Marshal.PtrToStringAnsi(messagePtr);
OutlineDetector.DeletePointerArray(messagePtr);
if (string.IsNullOrEmpty(message))
{
MessageBox.Show("当前没有可以导出的数据!");
return;
}
DrawerData drawerData = new DrawerData();
drawerData.AddBufferData(message);
drawerData.SaveAs(ofd.FileName);
}
}
///
/// 数据回写点击事件.
///
/// The sender.
/// The e.
private void bbtnPushBack_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
// 调用C++函数获取字符串
//IntPtr messagePtr = OutlineDetector.GetContourData();
IntPtr ptrPolygons = OutlineDetector.GetContourDataPtr();
//// 将IntPtr转换为C#的字符串
//string message = Marshal.PtrToStringAnsi(messagePtr);
//OutlineDetector.DeletePointerArray(messagePtr);
//if(!string.IsNullOrEmpty(message))
if(ptrPolygons != IntPtr.Zero)
{
//DrawerData.XyAddPolygonTree(this.pXy, ptrPolygons, $"Layer M 轮廓线\r\n{message}");
DrawerData.XyAddPolygonTree(this.pXy, ptrPolygons, $"轮廓线");
this.PushDataClick?.Invoke(sender, e);
MessageBox.Show("轮廓线已成功回写!");
}
}
}
}