Прямоугольник
//------------------------------------------------------------------------------
//
// Графический объект Rectangle. Copyright (c) 2023 Tiger Trade Capital AG. All rights reserved.
//
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Windows;
using System.Windows.Media;
using TigerTrade.Chart.Base;
using TigerTrade.Chart.Base.Enums;
using TigerTrade.Chart.Objects.Common;
using TigerTrade.Dx;
using TigerTrade.Dx.Enums;
namespace TigerTrade.Chart.Objects.Custom
{
[DataContract(Name = "RectangleObject", Namespace = "http://schemas.datacontract.org/2004/07/TigerTrade.Chart.Objects.Custom")]
[ChartObject("X_Rectangle", "Прямоугольник", 2, Type = typeof(RectangleObject))]
public sealed class RectangleObject : ObjectBase
{
private bool _drawBorder;
[DataMember(Name = "DrawBorder")]
[Category("Граница"), DisplayName("Граница")]
public bool DrawBorder
{
get => _drawBorder;
set
{
if (value == _drawBorder)
{
return;
}
_drawBorder = value;
OnPropertyChanged();
}
}
private XBrush _lineBrush;
private XPen _linePen;
private XColor _lineColor;
[DataMember(Name = "LineColor")]
[Category("Граница"), DisplayName("Цвет линии")]
public XColor LineColor
{
get => _lineColor;
set
{
if (value == _lineColor)
{
return;
}
_lineColor = value;
_lineBrush = new XBrush(_lineColor);
_linePen = new XPen(_lineBrush, LineWidth, LineStyle);
OnPropertyChanged();
}
}
private int _lineWidth;
[DataMember(Name = "LineWidth")]
[Category("Граница"), DisplayName("Толщина линии")]
public int LineWidth
{
get => _lineWidth;
set
{
value = Math.Max(1, Math.Min(10, value));
if (value == _lineWidth)
{
return;
}
_lineWidth = value;
_linePen = new XPen(_lineBrush, _lineWidth, LineStyle);
OnPropertyChanged();
}
}
private XDashStyle _lineStyle;
[DataMember(Name = "LineStyle")]
[Category("Граница"), DisplayName("Стиль линии")]
public XDashStyle LineStyle
{
get => _lineStyle;
set
{
if (value == _lineStyle)
{
return;
}
_lineStyle = value;
_linePen = new XPen(_lineBrush, LineWidth, _lineStyle);
OnPropertyChanged();
}
}
private bool _drawBack;
[DataMember(Name = "DrawBack")]
[Category("Фон"), DisplayName("Фон")]
public bool DrawBack
{
get => _drawBack;
set
{
if (value == _drawBack)
{
return;
}
_drawBack = value;
OnPropertyChanged();
}
}
private XBrush _backBrush;
private XColor _backColor;
[DataMember(Name = "BackColor")]
[Category("Фон"), DisplayName("Цвет фона")]
public XColor BackColor
{
get => _backColor;
set
{
if (value == _backColor)
{
return;
}
_backColor = value;
_backBrush = new XBrush(_backColor);
OnPropertyChanged();
}
}
protected override int PenWidth => LineWidth;
private bool _isObjectInArea;
public class RectangleInfo
{
public Point ControlPoint1;
public Point ControlPoint2;
public Point ExtraPoint1;
public Point ExtraPoint2;
public Rect Rectangle;
}
private RectangleInfo _rectInfo;
public RectangleObject()
{
DrawBorder = true;
LineColor = Colors.Black;
LineWidth = 1;
LineStyle = XDashStyle.Solid;
DrawBack = true;
BackColor = Color.FromArgb(30, 0, 0, 0);
}
protected override void Prepare()
{
var point1 = ToPoint(ControlPoints[0]);
var point2 = ToPoint(ControlPoints[1]);
var ep1 = ToPoint(ExtraPoints[0]);
var ep2 = ToPoint(ExtraPoints[1]);
var w = Canvas.ColumnWidth / 2.0;
var h = Canvas.StepHeight / 2.0;
var extendHeight = Canvas.StockType == ChartStockType.Clusters;
if (point1.X > point2.X)
{
point1.X += w;
point2.X -= w;
}
else
{
point1.X -= w;
point2.X += w;
}
if (extendHeight)
{
if (point1.Y > point2.Y)
{
point1.Y += h;
point2.Y -= h;
}
else
{
point1.Y -= h;
point2.Y += h;
}
}
if (ep1.X > ep2.X)
{
ep1.X += w;
ep2.X -= w;
}
else
{
ep1.X -= w;
ep2.X += w;
}
if (extendHeight)
{
if (ep1.Y > ep2.Y)
{
ep1.Y += h;
ep2.Y -= h;
}
else
{
ep1.Y -= h;
ep2.Y += h;
}
}
_rectInfo = new RectangleInfo
{
ControlPoint1 = point1,
ControlPoint2 = point2,
ExtraPoint1 = ep1,
ExtraPoint2 = ep2,
Rectangle = new Rect(point1, point2)
};
_isObjectInArea = Canvas.Rect.IntersectsWith(_rectInfo.Rectangle);
}
protected override void Draw(DxVisualQueue visual, ref List<ObjectLabelInfo> labels)
{
if (DrawBack)
{
visual.FillRectangle(_backBrush, _rectInfo.Rectangle);
}
if (DrawBorder)
{
visual.DrawRectangle(_linePen, _rectInfo.Rectangle);
}
}
public override void DrawControlPoints(DxVisualQueue visual)
{
if (_rectInfo == null)
{
return;
}
DrawControlPoint(visual, _rectInfo.ControlPoint1);
DrawControlPoint(visual, _rectInfo.ControlPoint2);
DrawControlPoint(visual, _rectInfo.ExtraPoint1);
DrawControlPoint(visual, _rectInfo.ExtraPoint2);
}
public override int GetControlPoint(int x, int y)
{
if (Canvas == null || _rectInfo == null)
{
return -1;
}
var points = new[] { _rectInfo.ControlPoint1, _rectInfo.ControlPoint2 };
for (var i = 0; i < points.Length; i++)
{
var distX = points[i].X - x;
var distY = points[i].Y - y;
if (distX * distX + distY * distY < 9.0 + PenWidth / 2.0)
{
return i;
}
}
return -1;
}
public override int GetExtraPoint(int x, int y)
{
if (Canvas == null || _rectInfo == null)
{
return -1;
}
var points = new[] { _rectInfo.ExtraPoint1, _rectInfo.ExtraPoint2 };
for (var i = 0; i < points.Length; i++)
{
var distX = points[i].X - x;
var distY = points[i].Y - y;
if (distX * distX + distY * distY < 9.0 + PenWidth / 2.0)
{
return i;
}
}
return -1;
}
protected override bool IsObjectInArea()
{
return _isObjectInArea;
}
protected override bool InObject(int x, int y)
{
if (_rectInfo == null)
{
return false;
}
return _rectInfo.Rectangle != Rect.Empty && _rectInfo.Rectangle.Contains(x, y);
}
protected override int GetMinDist(int x, int y)
{
var rect = _rectInfo.Rectangle;
var dx = Math.Min(rect.X + rect.Width - x, x - rect.X);
var dy = Math.Min(rect.Y + rect.Height - y, y - rect.Y);
var result = Math.Min(dx, dy);
return result > 0 ? (int)result : -1;
}
public override ObjectPoint[] ExtraPoints
{
get
{
var cp1 = ControlPoints[0];
var cp2 = ControlPoints[1];
var ep1 = new ObjectPoint(cp2.X, cp1.Y);
var ep2 = new ObjectPoint(cp1.X, cp2.Y);
var extraPoints = new[] { ep1, ep2 };
return extraPoints;
}
}
public override void ExtraPointChanged(int index, ObjectPoint op)
{
switch (index)
{
case 0:
ControlPoints[1].X = op.X;
ControlPoints[0].Y = op.Y;
break;
case 1:
ControlPoints[0].X = op.X;
ControlPoints[1].Y = op.Y;
break;
}
}
public override void ApplyTheme(IChartTheme theme)
{
base.ApplyTheme(theme);
LineColor = theme.ChartObjectLineColor;
BackColor = theme.ChartObjectFillColor;
}
public override void CopyTemplate(ObjectBase objectBase, bool style)
{
if (objectBase is RectangleObject obj)
{
DrawBorder = obj.DrawBorder;
LineColor = obj.LineColor;
LineWidth = obj.LineWidth;
LineStyle = obj.LineStyle;
DrawBack = obj.DrawBack;
BackColor = obj.BackColor;
}
base.CopyTemplate(objectBase, style);
}
}
}
Last updated