d533e4355d4c851426c30eefb1c45208784fafd7
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / BaseComponents / VectorGraphics / Shape.cs
1 /* 
2 * Copyright(c) 2021 Samsung Electronics Co., Ltd.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 using System;
19 using System.ComponentModel;
20 using System.Collections.ObjectModel;
21 using System.Collections.Generic;
22
23 namespace Tizen.NUI.BaseComponents.VectorGraphics
24 {
25     /// <summary>
26     /// Shape is a command list for drawing one shape groups It has own path data and properties for sync/asynchronous drawing
27     /// </summary>
28     /// <since_tizen> 9 </since_tizen>
29     public class Shape : Drawable
30     {
31         private Gradient fillGradient; //Added gradient
32         private Gradient strokeGradient; //Added gradient
33
34         /// <summary>
35         /// Creates an initialized Shape.
36         /// </summary>
37         /// <since_tizen> 9 </since_tizen>
38         public Shape() : this(Interop.Shape.New(), true)
39         {
40             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
41         }
42
43         internal Shape(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
44         {
45         }
46
47         /// <summary>
48         /// Enumeration for The fill rule of shape.
49         /// </summary>
50         /// <since_tizen> 9 </since_tizen>
51         public enum FillRuleType
52         {
53             /// <summary>
54             /// Draw a horizontal line from the point to a location outside the shape. Determine whether the direction of the line at each intersection point is up or down. The winding number is determined by summing the direction of each intersection. If the number is non zero, the point is inside the shape.
55             /// </summary>
56             Winding = 0,
57             /// <summary>
58             /// Draw a horizontal line from the point to a location outside the shape, and count the number of intersections. If the number of intersections is an odd number, the point is inside the shape.
59             /// </summary>
60             EvenOdd
61         }
62
63         /// <summary>
64         /// Enumeration for The cap style to be used for stroking the path.
65         /// </summary>
66         /// <since_tizen> 9 </since_tizen>
67         public enum StrokeCapType
68         {
69             /// <summary>
70             /// The end of lines is rendered as a square around the last point.
71             /// </summary>
72             Square = 0,
73             /// <summary>
74             /// The end of lines is rendered as a half-circle around the last point.
75             /// </summary>
76             Round,
77             /// <summary>
78             /// The end of lines is rendered as a full stop on the last point itself.
79             /// </summary>
80             Butt
81         }
82
83         /// <summary>
84         /// numeration for The join style to be used for stroking the path.
85         /// </summary>
86         /// <since_tizen> 9 </since_tizen>
87         public enum StrokeJoinType
88         {
89             /// <summary>
90             /// Used to render beveled line joins. The outer corner of the joined lines is filled by enclosing the triangular region of the corner with a straight line between the outer corners of each stroke.
91             /// </summary>
92             Bevel = 0,
93             /// <summary>
94             /// Used to render rounded line joins. Circular arcs are used to join two lines smoothly.
95             /// </summary>
96             Round,
97             /// <summary>
98             /// Used to render mitered line joins. The intersection of the strokes is clipped at a line perpendicular to the bisector of the angle between the strokes, at the distance from the intersection of the segments equal to the product of the miter limit value and the border radius.  This prevents long spikes being created.
99             /// </summary>
100             Miter
101         }
102
103         /// <summary>
104         /// The color to use for filling the path.
105         /// </summary>
106         /// <since_tizen> 9 </since_tizen>
107         public Color FillColor
108         {
109             get
110             {
111                 global::System.IntPtr cPtr = Interop.Shape.GetFillColor(BaseHandle.getCPtr(this));
112                 return Vector4.GetVector4FromPtr(cPtr);
113             }
114             set
115             {
116                 Interop.Shape.SetFillColor(BaseHandle.getCPtr(this), Vector4.getCPtr(value));
117                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
118             }
119         }
120
121         /// <summary>
122         /// The gradient to use for filling the path.
123         /// Even if FillColor is set, Gradient setting takes precedence.
124         /// </summary>
125         [EditorBrowsable(EditorBrowsableState.Never)]
126         public Gradient FillGradient
127         {
128             get
129             {
130                 global::System.IntPtr cPtr = Interop.Shape.GetFillGradient(BaseHandle.getCPtr(this));
131                 Gradient ret = new Gradient(cPtr, true);
132                 return ret;
133             }
134             set
135             {
136                 if (value != null)
137                 {
138                     Interop.Shape.SetFillGradient(BaseHandle.getCPtr(this), BaseHandle.getCPtr(value));
139                     if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
140                     fillGradient = value;
141                 }       
142             }
143         }
144
145         /// <summary>
146         /// The current fill rule of the shape.
147         /// </summary>
148         /// <since_tizen> 9 </since_tizen>
149         public FillRuleType FillRule
150         {
151             get
152             {
153                 return (FillRuleType)Interop.Shape.GetFillRule(BaseHandle.getCPtr(this));
154             }
155             set
156             {
157                 Interop.Shape.SetFillRule(BaseHandle.getCPtr(this), (int)value);
158                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
159             }
160         }
161
162         /// <summary>
163         /// The stroke width to use for stroking the path.
164         /// </summary>
165         /// <since_tizen> 9 </since_tizen>
166         public float StrokeWidth
167         {
168             get
169             {
170                 return Interop.Shape.GetStrokeWidth(BaseHandle.getCPtr(this));
171             }
172             set
173             {
174                 Interop.Shape.SetStrokeWidth(BaseHandle.getCPtr(this), value);
175                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
176             }
177         }
178
179         /// <summary>
180         /// The color to use for stroking the path.
181         /// </summary>
182         /// <since_tizen> 9 </since_tizen>
183         public Color StrokeColor
184         {
185             get
186             {
187                 global::System.IntPtr cPtr = Interop.Shape.GetStrokeColor(BaseHandle.getCPtr(this));
188                 return Vector4.GetVector4FromPtr(cPtr);
189             }
190             set
191             {
192                 Interop.Shape.SetStrokeColor(BaseHandle.getCPtr(this), Vector4.getCPtr(value));
193                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
194             }
195         }
196
197         /// <summary>
198         /// The gradient to use for stroking the path.
199         /// Even if StrokeColor is set, Gradient setting takes precedence.
200         /// </summary>
201         [EditorBrowsable(EditorBrowsableState.Never)]
202         public Gradient StrokeGradient
203         {
204             get
205             {
206                 global::System.IntPtr cPtr = Interop.Shape.GetStrokeGradient(BaseHandle.getCPtr(this));
207                 Gradient ret = new Gradient(cPtr, true);
208                 return ret;
209             }
210             set
211             {
212                 if (value != null)
213                 {
214                     Interop.Shape.SetStrokeGradient(BaseHandle.getCPtr(this), BaseHandle.getCPtr(value));
215                     if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
216                     strokeGradient = value;
217                 }       
218             }
219         }
220
221         /// <summary>
222         /// The cap style to use for stroking the path. The cap will be used for capping the end point of a open subpath.
223         /// </summary>
224         /// <since_tizen> 9 </since_tizen>
225         public StrokeCapType StrokeCap
226         {
227             get
228             {
229                 return (StrokeCapType)Interop.Shape.GetStrokeCap(BaseHandle.getCPtr(this));
230             }
231             set
232             {
233                 Interop.Shape.SetStrokeCap(BaseHandle.getCPtr(this), (int)value);
234                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
235             }
236         }
237
238         /// <summary>
239         /// The join style to use for stroking the path.
240         /// The join style will be used for joining the two line segment while stroking the path.
241         /// </summary>
242         /// <since_tizen> 9 </since_tizen>
243         public StrokeJoinType StrokeJoin
244         {
245             get
246             {
247                 return (StrokeJoinType)Interop.Shape.GetStrokeJoin(BaseHandle.getCPtr(this));
248             }
249             set
250             {
251                 Interop.Shape.SetStrokeJoin(BaseHandle.getCPtr(this), (int)value);
252                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
253             }
254         }
255
256         /// <summary>
257         /// The stroke dash pattern. The dash pattern is specified dash pattern.
258         /// </summary>
259         /// <exception cref="ArgumentNullException"> Thrown when value is null. </exception>
260         /// <since_tizen> 9 </since_tizen>
261         public ReadOnlyCollection<float> StrokeDash
262         {
263             get
264             {
265                 List<float> retList = new List<float>();
266                 int patternCount = Interop.Shape.GetStrokeDashCount(BaseHandle.getCPtr(this));
267                 for (int i = 0; i < patternCount; i++)
268                 {
269                     retList.Add(Interop.Shape.GetStrokeDashIndexOf(BaseHandle.getCPtr(this), i));
270                 }
271
272                 ReadOnlyCollection<float> ret = new ReadOnlyCollection<float>(retList);
273                 return ret;
274             }
275             set
276             {
277                 if (value == null)
278                 {
279                     throw new ArgumentNullException(nameof(value));
280                 }
281                 float[] pattern = new float[value.Count];
282                 for (int i = 0; i < value.Count; i++)
283                 {
284                     pattern[i] = value[i];
285                 }
286                 Interop.Shape.SetStrokeDash(BaseHandle.getCPtr(this), pattern, value.Count);
287                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
288             }
289         }
290
291         /// <summary>
292         /// Append the given rectangle with rounded corner to the path.
293         /// The roundedCorner arguments specify the radii of the ellipses defining the
294         /// corners of the rounded rectangle.
295         ///
296         /// roundedCorner are specified in terms of width and height respectively.
297         ///
298         /// If roundedCorner's values are 0, then it will draw a rectangle without rounded corner.
299         /// </summary>
300         /// <param name="x">X co-ordinate of the rectangle.</param>
301         /// <param name="y">Y co-ordinate of the rectangle.</param>
302         /// <param name="width">Width of the rectangle.</param>
303         /// <param name="height">Height of the rectangle.</param>
304         /// <param name="roundedCornerX">The x radius of the rounded corner and should be in range [ 0 to w/2 ].</param>
305         /// <param name="roundedCornerY">The y radius of the rounded corner and should be in range [ 0 to w/2 ].</param>
306         /// <returns>True when it's successful. False otherwise.</returns>
307         /// <since_tizen> 9 </since_tizen>
308         public bool AddRect(float x, float y, float width, float height, float roundedCornerX, float roundedCornerY)
309         {
310             bool ret = Interop.Shape.AddRect(BaseHandle.getCPtr(this), x, y, width, height, roundedCornerX, roundedCornerY);
311             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
312             return ret;
313         }
314
315         /// <summary>
316         /// Append a circle with given center and x,y-axis radius
317         /// </summary>
318         /// <param name="x">X co-ordinate of the center of the circle.</param>
319         /// <param name="y">Y co-ordinate of the center of the circle.</param>
320         /// <param name="radiusX">X axis radius.</param>
321         /// <param name="radiusY">Y axis radius.</param>
322         /// <returns>True when it's successful. False otherwise.</returns>
323         /// <since_tizen> 9 </since_tizen>
324         public bool AddCircle(float x, float y, float radiusX, float radiusY)
325         {
326             bool ret = Interop.Shape.AddCircle(BaseHandle.getCPtr(this), x, y, radiusX, radiusY);
327             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
328             return ret;
329         }
330
331         /// <summary>
332         /// Append the arcs.
333         /// </summary>
334         /// <param name="x">X co-ordinate of end point of the arc.</param>
335         /// <param name="y">Y co-ordinate of end point of the arc.</param>
336         /// <param name="radius">Radius of arc</param>
337         /// <param name="startAngle">Start angle (in degrees) where the arc begins.</param>
338         /// <param name="sweep">The Angle measures how long the arc will be drawn.</param>
339         /// <param name="pie">If True, the area is created by connecting start angle point and sweep angle point of the drawn arc. If false, it doesn't.</param>
340         /// <returns>True when it's successful. False otherwise.</returns>
341         /// <since_tizen> 9 </since_tizen>
342         public bool AddArc(float x, float y, float radius, float startAngle, float sweep, bool pie)
343         {
344             bool ret = Interop.Shape.AddArc(BaseHandle.getCPtr(this), x, y, radius, startAngle, sweep, pie);
345             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
346             return ret;
347         }
348
349         /// <summary>
350         /// Add a point that sets the given point as the current point,
351         /// implicitly starting a new subpath and closing the previous one.
352         /// </summary>
353         /// <param name="x">X co-ordinate of the current point.</param>
354         /// <param name="y">Y co-ordinate of the current point.</param>
355         /// <returns>True when it's successful. False otherwise.</returns>
356         /// <since_tizen> 9 </since_tizen>
357         public bool AddMoveTo(float x, float y)
358         {
359             bool ret = Interop.Shape.AddMoveTo(BaseHandle.getCPtr(this), x, y);
360             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
361             return ret;
362         }
363
364         /// <summary>
365         /// Adds a straight line from the current position to the given end point.
366         /// After the line is drawn, the current position is updated to be at the
367         /// end point of the line.
368         /// If no current position present, it draws a line to itself, basically * a point.
369         /// </summary>
370         /// <param name="x">X co-ordinate of end point of the line.</param>
371         /// <param name="y">Y co-ordinate of end point of the line.</param>
372         /// <returns>True when it's successful. False otherwise.</returns>
373         /// <since_tizen> 9 </since_tizen>
374         public bool AddLineTo(float x, float y)
375         {
376             bool ret = Interop.Shape.AddLineTo(BaseHandle.getCPtr(this), x, y);
377             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
378             return ret;
379         }
380
381         /// <summary>
382         /// Adds a cubic Bezier curve between the current position and the
383         /// given end point (lineEndPoint) using the control points specified by
384         /// (controlPoint1), and (controlPoint2). After the path is drawn,
385         /// the current position is updated to be at the end point of the path.
386         /// </summary>
387         /// <param name="controlPoint1X">X co-ordinate of 1st control point.</param>
388         /// <param name="controlPoint1Y">Y co-ordinate of 1st control point.</param>
389         /// <param name="controlPoint2X">X co-ordinate of 2nd control point.</param>
390         /// <param name="controlPoint2Y">Y co-ordinate of 2nd control point.</param>
391         /// <param name="endPointX">X co-ordinate of end point of the line.</param>
392         /// <param name="endPointY">Y co-ordinate of end point of the line.</param>
393         /// <returns>True when it's successful. False otherwise.</returns>
394         /// <since_tizen> 9 </since_tizen>
395         public bool AddCubicTo(float controlPoint1X, float controlPoint1Y, float controlPoint2X, float controlPoint2Y, float endPointX, float endPointY)
396         {
397             bool ret = Interop.Shape.AddCubicTo(BaseHandle.getCPtr(this), controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, endPointX, endPointY);
398             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
399             return ret;
400         }
401
402         /// <summary>
403         /// Closes the current subpath by drawing a line to the beginning of the
404         /// subpath, automatically starting a new path. The current point of the
405         /// new path is (0, 0).
406         /// If the subpath does not contain any points, this function does nothing.
407         /// </summary>
408         /// <returns>True when it's successful. False otherwise.</returns>
409         /// <since_tizen> 9 </since_tizen>
410         public bool Close()
411         {
412             bool ret = Interop.Shape.Close(BaseHandle.getCPtr(this));
413             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
414             return ret;
415         }
416
417         /// <summary>
418         /// Reset the added path(rect, circle, path, etc...) information.
419         /// Color and Stroke information are keeped.
420         /// </summary>
421         /// <returns>True when it's successful. False otherwise.</returns>
422         /// <since_tizen> 9 </since_tizen>
423         public bool ResetPath()
424         {
425             bool ret = Interop.Shape.ResetPath(BaseHandle.getCPtr(this));
426             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
427             return ret;
428         }
429     }
430 }