FastReport

Форк
0
184 строки · 7.7 Кб
1
using System.Drawing;
2
using System.Drawing.Drawing2D;
3
using FastReport.Utils;
4
using System.ComponentModel;
5

6
namespace FastReport.Gauge.Radial
7
{
8
    /// <summary>
9
    /// Represents a linear pointer.
10
    /// </summary>
11
#if !DEBUG
12
    [DesignTimeVisible(false)]
13
#endif
14
    public class RadialPointer : GaugePointer
15
    {
16
        #region Fields
17
        private RadialScale scale;
18
        private bool gradAutoRotate;
19
        #endregion // Fields
20

21
        /// <summary>
22
        /// Gets or sets the value, indicating that gradient should be rotated automatically
23
        /// </summary>
24
        [Browsable(true)]
25
        public bool GradientAutoRotate
26
        {
27
            get { return gradAutoRotate; }
28
            set { gradAutoRotate = value; }
29
        }
30

31
        #region Constructors
32

33
        /// <summary>
34
        /// Initializes a new instance of the <see cref="RadialPointer"/>
35
        /// </summary>
36
        /// <param name="parent">The parent gauge object.</param>
37
        /// <param name="scale">The scale object.</param>
38
        public RadialPointer(GaugeObject parent, RadialScale scale) : base(parent)
39
        {
40
            this.scale = scale;
41
            gradAutoRotate = true;
42
        }
43

44
        #endregion // Constructors
45

46
        #region Private Methods
47

48
        private void DrawHorz(FRPaintEventArgs e)
49
        {
50
            IGraphics g = e.Graphics;
51
            Pen pen = e.Cache.GetPen(BorderColor, BorderWidth * e.ScaleX, DashStyle.Solid);
52

53
            PointF center = (Parent as RadialGauge).Center;
54
            float circleWidth = Parent.Width / 16f;
55
            float circleHeight = Parent.Height / 16f;
56
            RectangleF pointerCircle = new RectangleF(center.X - circleWidth / 2 * e.ScaleX, center.Y - circleHeight / 2 * e.ScaleY, circleWidth * e.ScaleX, circleHeight * e.ScaleY);
57

58
            //double rotateTo = (scale.AverageValue - Parent.Minimum);
59
            double startAngle = -135 * RadialGauge.Radians;
60
            double angle = (Parent.Value - Parent.Minimum) / scale.StepValue * scale.MajorStep * RadialGauge.Radians;
61
            if ((Parent as RadialGauge).Type == RadialGaugeType.Semicircle)
62
            {
63
                if ((Parent as RadialGauge).Position == RadialGaugePosition.Bottom || (Parent as RadialGauge).Position == RadialGaugePosition.Top)
64
                {
65
                    startAngle = -90 * RadialGauge.Radians;
66
                    if ((Parent as RadialGauge).Position == RadialGaugePosition.Bottom)
67
                        angle *= -1;
68
                }
69
                else if ((Parent as RadialGauge).Position == RadialGaugePosition.Left)
70
                    startAngle = -180 * RadialGauge.Radians;
71
                else if ((Parent as RadialGauge).Position == RadialGaugePosition.Right)
72
                {
73
                    startAngle = -180 * RadialGauge.Radians;
74
                    angle *= -1;
75
                }
76
            }
77
            else if (RadialUtils.IsQuadrant(Parent))
78
            {
79
                if (RadialUtils.IsLeft(Parent) && RadialUtils.IsTop(Parent))
80
                    startAngle = -90 * RadialGauge.Radians;
81
                else if (RadialUtils.IsLeft(Parent) && RadialUtils.IsBottom(Parent))
82
                    startAngle = -180 * RadialGauge.Radians;
83
                else if (RadialUtils.IsRight(Parent) && RadialUtils.IsTop(Parent))
84
                    startAngle = 90 * RadialGauge.Radians;
85
                else if (RadialUtils.IsRight(Parent) && RadialUtils.IsBottom(Parent))
86
                {
87
                    startAngle = 180 * RadialGauge.Radians;
88
                    angle *= -1;
89
                }
90
            }
91
            //double startAngle = rotateTo / scale.StepValue * -scale.MajorStep * RadialGauge.Radians;
92

93
            float ptrLineY = center.Y - pointerCircle.Width / 2 - pointerCircle.Width / 5;
94
            float ptrLineY1 = scale.AvrTick.Y + scale.MinorTicks.Length * 1.7f;
95
            float ptrLineWidth = circleWidth / 3 * e.ScaleX;
96
            PointF[] pointerPerpStrt = new PointF[2];
97
            pointerPerpStrt[0] = new PointF(center.X - ptrLineWidth, ptrLineY);
98
            pointerPerpStrt[1] = new PointF(center.X + ptrLineWidth, ptrLineY);
99

100
            PointF[] pointerPerpEnd = new PointF[2];
101
            pointerPerpEnd[0] = new PointF(center.X - ptrLineWidth / 3, ptrLineY1);
102
            pointerPerpEnd[1] = new PointF(center.X + ptrLineWidth / 3, ptrLineY1);
103

104

105
            pointerPerpStrt = RadialUtils.RotateVector(pointerPerpStrt, startAngle, center);
106
            pointerPerpEnd = RadialUtils.RotateVector(pointerPerpEnd, startAngle, center);
107

108
            PointF[] rotatedPointerPerpStrt = RadialUtils.RotateVector(pointerPerpStrt, angle, center);
109
            PointF[] rotatedPointerPerpEnd = RadialUtils.RotateVector(pointerPerpEnd, angle, center);
110

111
            //calc brush rect
112
            float x = 0, y = 0, dx = 0, dy = 0;
113
            if (angle / RadialGauge.Radians >= 0 && angle / RadialGauge.Radians < 45)
114
            {
115
                x = rotatedPointerPerpEnd[1].X;
116
                y = rotatedPointerPerpEnd[0].Y - (rotatedPointerPerpEnd[0].Y - pointerCircle.Y);
117
                dx = pointerCircle.X + pointerCircle.Width - rotatedPointerPerpEnd[0].X;
118
                dy = rotatedPointerPerpEnd[0].Y - pointerCircle.Y;
119
            }
120
            else if (angle / RadialGauge.Radians >= 45 && angle / RadialGauge.Radians < 90)
121
            {
122
                x = rotatedPointerPerpEnd[0].X;
123
                y = rotatedPointerPerpEnd[1].Y;
124
                dx = pointerCircle.X + pointerCircle.Width - rotatedPointerPerpEnd[0].X;
125
                dy = pointerCircle.Y + pointerCircle.Height - rotatedPointerPerpEnd[0].Y;
126
            }
127
            else if (angle / RadialGauge.Radians >= 90 && angle / RadialGauge.Radians < 135)
128
            {
129
                x = rotatedPointerPerpEnd[0].X;
130
                y = rotatedPointerPerpEnd[1].Y;
131
                dx = pointerCircle.X + pointerCircle.Width - rotatedPointerPerpEnd[0].X;
132
                dy = pointerCircle.Y + pointerCircle.Height - rotatedPointerPerpEnd[1].Y;
133
            }
134
            else if (angle / RadialGauge.Radians >= 135 && angle / RadialGauge.Radians < 225)
135
            {
136
                x = pointerCircle.X;
137
                y = rotatedPointerPerpEnd[0].Y;
138
                dx = rotatedPointerPerpEnd[1].X - pointerCircle.X;
139
                dy = pointerCircle.Y + pointerCircle.Height - rotatedPointerPerpEnd[0].Y;
140
            }
141
            else if (angle / RadialGauge.Radians >= 225)
142
            {
143
                x = pointerCircle.X;
144
                y = pointerCircle.Y;
145
                dx = rotatedPointerPerpEnd[0].X - pointerCircle.X;
146
                dy = rotatedPointerPerpEnd[1].Y - pointerCircle.Y;
147
            }
148
            RectangleF brushRect = new RectangleF(x, y, dx, dy);
149
            if (gradAutoRotate && Fill is LinearGradientFill)
150
            {
151
                (Fill as LinearGradientFill).Angle = (int)(startAngle / RadialGauge.Radians + angle / RadialGauge.Radians) + 90;
152
            }
153
            Brush brush = Fill.CreateBrush(brushRect, e.ScaleX, e.ScaleY);
154

155
            PointF[] p = new PointF[]
156
            {
157
                rotatedPointerPerpStrt[0],
158
                rotatedPointerPerpStrt[1],
159
                rotatedPointerPerpEnd[1],
160
                rotatedPointerPerpEnd[0],
161
            };
162
            GraphicsPath path = new GraphicsPath();
163
            path.AddLines(p);
164
            path.AddLine(p[3], p[0]);
165

166
            g.FillAndDrawEllipse(pen, brush, pointerCircle);
167

168
            g.FillAndDrawPath(pen, brush, path);
169
        }
170

171
        #endregion // Private Methods
172

173
        #region Public Methods
174

175
        /// <inheritdoc/>
176
        public override void Draw(FRPaintEventArgs e)
177
        {
178
            base.Draw(e);
179
            DrawHorz(e);
180
        }
181

182
        #endregion // Public Methods
183
    }
184
}
185

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.