using BetterGenshinImpact.GameTask.Model.Area.Converter;
using BetterGenshinImpact.View.Drawable;
using OpenCvSharp;
using System;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using Vanara.PInvoke;
namespace BetterGenshinImpact.GameTask.Model.Area;
///
/// 区域基类
/// 用于描述一个区域,可以是一个矩形,也可以是一个点
///
public class Region : IDisposable
{
public int X { get; set; }
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public int Top
{
get => Y;
set => Y = value;
}
///
/// Gets the y-coordinate that is the sum of the Y and Height property values of this Rect structure.
///
public int Bottom => Y + Height;
///
/// Gets the x-coordinate of the left edge of this Rect structure.
///
public int Left
{
get => X;
set => X = value;
}
///
/// Gets the x-coordinate that is the sum of X and Width property values of this Rect structure.
///
public int Right => X + Width;
///
/// 存放OCR识别的结果文本
///
public string Text { get; set; } = string.Empty;
public Region()
{
}
public Region(int x, int y, int width, int height, Region? owner = null, INodeConverter? converter = null)
{
X = x;
Y = y;
Width = width;
Height = height;
Prev = owner;
PrevConverter = converter;
}
public Region(Rect rect, Region? owner = null, INodeConverter? converter = null) : this(rect.X, rect.Y, rect.Width, rect.Height, owner, converter)
{
}
public Region? Prev { get; }
///
/// 本区域节点向上一个区域节点坐标的转换器
///
public INodeConverter? PrevConverter { get; }
// public List? NextChildren { get; protected set; }
///
/// 后台点击【自己】的中心
///
public void BackgroundClick()
{
User32.GetCursorPos(out var p);
this.Move(); // 必须移动实际鼠标
TaskContext.Instance().PostMessageSimulator.LeftButtonClickBackground();
Thread.Sleep(10);
DesktopRegion.DesktopRegionMove(p.X, p.Y); // 鼠标移动回原来位置
}
///
/// 点击【自己】的中心
/// region.Derive(x,y).Click() 等效于 region.ClickTo(x,y)
///
public void Click()
{
// 相对自己是 0, 0 坐标
ClickTo(0, 0, Width, Height);
}
///
/// 点击区域内【指定位置】
/// region.Derive(x,y).Click() 等效于 region.ClickTo(x,y)
///
///
///
public void ClickTo(int x, int y)
{
ClickTo(x, y, 0, 0);
}
public void ClickTo(double dx, double dy)
{
var x = (int)Math.Round(dx);
var y = (int)Math.Round(dy);
ClickTo(x, y, 0, 0);
}
///
/// 点击区域内【指定矩形区域】的中心
///
///
///
///
///
///
public void ClickTo(int x, int y, int w, int h)
{
var res = ConvertRes.ConvertPositionToTargetRegion(x, y, w, h, this);
res.TargetRegion.DesktopRegionClick(res.X, res.Y, res.Width, res.Height);
}
///
/// 移动到【自己】的中心
/// region.Derive(x,y).Move() 等效于 region.MoveTo(x,y)
///
public void Move()
{
// 相对自己是 0, 0 坐标
MoveTo(0, 0, Width, Height);
}
///
/// 移动到区域内【指定位置】
/// region.Derive(x,y).Move() 等效于 region.MoveTo(x,y)
///
///
///
public void MoveTo(int x, int y)
{
MoveTo(x, y, 0, 0);
}
///
/// 移动到区域内【指定矩形区域】的中心
///
///
///
///
///
///
public void MoveTo(int x, int y, int w, int h)
{
var res = ConvertRes.ConvertPositionToTargetRegion(x, y, w, h, this);
res.TargetRegion.DesktopRegionMove(res.X, res.Y, res.Width, res.Height);
}
///
/// 直接在遮罩窗口绘制【自己】
///
///
///
public void DrawSelf(string name, Pen? pen = null)
{
// 相对自己是 0, 0 坐标
DrawRect(0, 0, Width, Height, name, pen);
}
///
/// 直接在遮罩窗口绘制当前区域下的【指定区域】
///
///
///
///
///
///
///
public void DrawRect(int x, int y, int w, int h, string name, Pen? pen = null)
{
var drawable = ToRectDrawable(x, y, w, h, name, pen);
VisionContext.Instance().DrawContent.PutRect(name, drawable);
}
public void DrawRect(Rect rect, string name, Pen? pen = null)
{
var drawable = ToRectDrawable(rect.X, rect.Y, rect.Width, rect.Height, name, pen);
VisionContext.Instance().DrawContent.PutRect(name, drawable);
}
///
/// 转换【自己】到遮罩窗口绘制矩形
///
///
///
///
public RectDrawable SelfToRectDrawable(string name, Pen? pen = null)
{
// 相对自己是 0, 0 坐标
return ToRectDrawable(0, 0, Width, Height, name, pen);
}
///
/// 转换【指定区域】到遮罩窗口绘制矩形
///
///
///
///
///
public RectDrawable ToRectDrawable(Rect rect, string name, Pen? pen = null)
{
return ToRectDrawable(rect.X, rect.Y, rect.Width, rect.Height, name, pen);
}
///
/// 转换【指定区域】到遮罩窗口绘制矩形
///
///
///
///
///
///
///
///
///
public RectDrawable ToRectDrawable(int x, int y, int w, int h, string name, Pen? pen = null)
{
var res = ConvertRes.ConvertPositionToTargetRegion(x, y, w, h, this);
return res.TargetRegion.ConvertToRectDrawable(res.X, res.Y, res.Width, res.Height, pen, name);
}
///
/// 转换【指定直线】到遮罩窗口绘制直线
///
///
///
///
///
///
///
///
public LineDrawable ToLineDrawable(int x1, int y1, int x2, int y2, string name, Pen? pen = null)
{
var res1 = ConvertRes.ConvertPositionToTargetRegion(x1, y1, 0, 0, this);
var res2 = ConvertRes.ConvertPositionToTargetRegion(x2, y2, 0, 0, this);
return res1.TargetRegion.ConvertToLineDrawable(res1.X, res1.Y, res2.X, res2.Y, pen, name);
}
public void DrawLine(int x1, int y1, int x2, int y2, string name, Pen? pen = null)
{
var drawable = ToLineDrawable(x1, y1, x2, y2, name, pen);
VisionContext.Instance().DrawContent.PutLine(name, drawable);
}
public Rect ConvertSelfPositionToGameCaptureRegion()
{
return ConvertPositionToGameCaptureRegion(X, Y, Width, Height);
}
public Rect ConvertPositionToGameCaptureRegion(int x, int y, int w, int h)
{
var res = ConvertRes.ConvertPositionToTargetRegion(x, y, w, h, this);
return res.ToRect();
}
public (int, int) ConvertPositionToGameCaptureRegion(int x, int y)
{
var res = ConvertRes.ConvertPositionToTargetRegion(x, y, 0, 0, this);
return (res.X, res.Y);
}
public (int, int) ConvertPositionToDesktopRegion(int x, int y)
{
var res = ConvertRes.ConvertPositionToTargetRegion(x, y, 0, 0, this);
return (res.X, res.Y);
}
public Rect ToRect()
{
return new Rect(X, Y, Width, Height);
}
///
/// 生成一个新的区域
/// 请使用 using var newRegion
///
///
public ImageRegion ToImageRegion()
{
if (this is ImageRegion imageRegion)
{
Debug.WriteLine("ToImageRegion 但已经是 ImageRegion");
return imageRegion;
}
var res = ConvertRes.ConvertPositionToTargetRegion(0, 0, Width, Height, this);
var newRegion = new ImageRegion(new Mat(res.TargetRegion.SrcMat, res.ToRect()), X, Y, Prev, PrevConverter);
return newRegion;
}
public bool IsEmpty()
{
return Width == 0 && Height == 0 && X == 0 && Y == 0;
}
///
/// 语义化包装
///
///
public bool IsExist()
{
return !IsEmpty();
}
public void Dispose()
{
// 子节点全部释放
// NextChildren?.ForEach(x => x.Dispose());
}
///
/// 派生一个点类型的区域
///
///
///
///
public Region Derive(int x, int y)
{
return Derive(x, y, 0, 0);
}
///
/// 派生一个矩形类型的区域
///
///
///
///
///
///
public Region Derive(int x, int y, int w, int h)
{
return new Region(x, y, w, h, this, new TranslationConverter(x, y));
}
public Region Derive(Rect rect)
{
return Derive(rect.X, rect.Y, rect.Width, rect.Height);
}
}