# Прямоугольник

```
//------------------------------------------------------------------------------
//
// Графический объект 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);
        }
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://support.tiger.com/razrabotka-dlya-tiger.trade-windows/primery-graficheskikh-obektov/pryamougolnik.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
