[NUI] CanvasView: Add ClipPath and Mask feature for Drawable (#3346)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / BaseComponents / VectorGraphics / Drawable.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 using System;
18 using System.ComponentModel;
19
20 namespace Tizen.NUI.BaseComponents.VectorGraphics
21 {
22     /// <summary>
23     /// Drawable is a object class for drawing a vector primitive.
24     /// </summary>
25     /// <since_tizen> 9 </since_tizen>
26     public class Drawable : BaseHandle
27     {
28         /// <summary>
29         /// Creates an initialized drawable.
30         /// </summary>
31         [EditorBrowsable(EditorBrowsableState.Never)]
32         private Drawable() { }
33
34         internal Drawable(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
35         {
36         }
37
38         /// <summary>
39         /// Enumeration indicating the type used in the masking of two objects - the mask drawable and the own drawable.
40         /// </summary>
41         [EditorBrowsable(EditorBrowsableState.Never)]
42         public enum MaskType
43         {
44             /// <summary>
45             /// The pixels of the own drawable and the mask drawable are alpha blended. As a result, only the part of the own drawable, which intersects with the mask drawable is visible.
46             /// </summary>
47             Alpha = 0,
48             /// <summary>
49             /// The pixels of the own drawable and the complement to the mask drawable's pixels are alpha blended. As a result, only the part of the own which is not covered by the mask is visible.
50             /// </summary>
51             AlphaInverse
52         }
53
54         /// <summary>
55         /// The transparency level [0 ~ 1.0], 0 means totally transparent, while 1 means opaque.
56         /// </summary>
57         /// <since_tizen> 9 </since_tizen>
58         public float Opacity
59         {
60             get
61             {
62                 return Interop.Drawable.GetOpacity(BaseHandle.getCPtr(this));
63             }
64             set
65             {
66                 Interop.Drawable.SetOpacity(BaseHandle.getCPtr(this), value);
67                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
68             }
69         }
70
71         /// <summary>
72         /// The bounding box of the drawable object to which no transformation has been applied.
73         /// </summary>
74         /// <remarks>
75         /// The bounding box doesn't indicate the rendering region in the result but primitive region of the object.
76         /// </remarks>
77         /// <remarks>
78         /// The float type Rectangle class is not ready yet.
79         /// Therefore, it transmits data in Vector4 class.
80         /// This type should later be changed to the appropriate data type.
81         /// </remarks>
82         /// <code>
83         ///  Shape shape = new Shape()
84         ///  {      
85         ///      FillColor = new Color(1.0f, 0.0f, 0.0f, 1.0f)
86         ///  };
87         ///  shape.AddRect(0.0f, 0.0f, 100.0f, 100.0f, 0.0f, 0.0f);
88         ///  float boundingBoxX = shape.BoundingBox[0];      // boundingBoxX will be 0.
89         ///  float boundingBoxY = shape.BoundingBox[1];      // boundingBoxY will be 0.
90         ///  float boundingBoxWidth = shape.BoundingBox[2];  // boundingBoxWidth will be 100.
91         ///  float boundingBoxHeight = shape.BoundingBox[3]; // boundingBoxHeight will be 100.
92         /// </code>
93         [EditorBrowsable(EditorBrowsableState.Never)]
94         public Vector4 BoundingBox
95         {
96             get
97             {
98                 global::System.IntPtr cPtr = Interop.Drawable.GetBoundingBox(BaseHandle.getCPtr(this));
99                 return Vector4.GetVector4FromPtr(cPtr);
100             }
101         }
102
103         /// <summary>
104         /// The intersection with clip drawable is determined and only the resulting pixels from own drawable are rendered.
105         /// </summary>
106         /// <param name="clip">The clip drawable object.</param>
107         /// <exception cref="Exception"> Drawable clpping failed. </exception>
108         /// <exception cref="ArgumentNullException"> Thrown when drawable is null. </exception>
109         [EditorBrowsable(EditorBrowsableState.Never)]
110         public void ClipPath(Drawable clip)
111         {
112             if (clip == null)
113             {
114                 throw new ArgumentNullException(nameof(clip));
115             }
116             bool ret = Interop.Drawable.SetClipPath(View.getCPtr(this), BaseHandle.getCPtr(clip));
117             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
118             if (!ret)
119             {
120                 throw new Exception("Drawable clipping failed or clip drawable is already added other drawable or canvas.");
121             }
122         }
123
124         /// <summary>
125         /// The pixels of mask drawable and own drawable are blended according to MaskType.
126         /// </summary>
127         /// <param name="mask">The mask drawable object.</param>
128         /// <param name="type">The masking type.</param>
129         /// <exception cref="Exception"> Drawable masking failed. </exception>
130         /// <exception cref="ArgumentNullException"> Thrown when drawable is null. </exception>
131         [EditorBrowsable(EditorBrowsableState.Never)]
132         public void Mask(Drawable mask, MaskType type)
133         {
134             if (mask == null)
135             {
136                 throw new ArgumentNullException(nameof(mask));
137             }
138             bool ret = Interop.Drawable.SetMask(View.getCPtr(this), BaseHandle.getCPtr(mask), (int)type);
139             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
140             if (!ret)
141             {
142                 throw new Exception("Drawable masking failed or mask drawable is already added other drawable or canvas.");
143             }
144         }
145
146         /// <summary>
147         /// Set the angle of rotation transformation.
148         /// </summary>
149         /// <param name="degree">The degree value of angle.</param>
150         /// <returns>True when it's successful. False otherwise.</returns>
151         /// <since_tizen> 9 </since_tizen>
152         public bool Rotate(float degree)
153         {
154             bool ret = Interop.Drawable.Rotate(BaseHandle.getCPtr(this), degree);
155             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
156             return ret;
157         }
158
159         /// <summary>
160         /// Set the scale value of scale transformation.
161         /// </summary>
162         /// <param name="factor">The scale factor value.</param>
163         /// <returns>True when it's successful. False otherwise.</returns>
164         /// <since_tizen> 9 </since_tizen>
165         public bool Scale(float factor)
166         {
167             bool ret = Interop.Drawable.Scale(BaseHandle.getCPtr(this), factor);
168             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
169             return ret;
170         }
171
172         /// <summary>
173         /// Set the matrix value for affine transform.
174         /// </summary>
175         /// <param name="matrix">The float type array of 3x3 matrix.</param>
176         /// <returns>True when it's successful. False otherwise.</returns>
177         /// <exception cref="ArgumentNullException"> Thrown when matrix is null. </exception>
178         /// <exception cref="ArgumentException"> Thrown when matrix array length is not 9. </exception>
179         /// <since_tizen> 9 </since_tizen>
180         public bool Transform(float[] matrix)
181         {
182             if (matrix == null)
183             {
184                 throw new ArgumentNullException(nameof(matrix));
185             }
186             if (matrix.Length != 9)
187             {
188                 throw new ArgumentException("matrix array length is not 9.", nameof(matrix));
189             }
190             bool ret = Interop.Drawable.Transform(BaseHandle.getCPtr(this), matrix);
191             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
192             return ret;
193         }
194
195         /// <summary>
196         /// Set the x, y movement value of translate transformation.
197         /// </summary>
198         /// <param name="x">The x-axis movement value.</param>
199         /// <param name="y">The y-axis movement value.</param>
200         /// <returns>True when it's successful. False otherwise.</returns>
201         /// <since_tizen> 9 </since_tizen>
202         public bool Translate(float x, float y)
203         {
204             bool ret = Interop.Drawable.Translate(BaseHandle.getCPtr(this), x, y);
205             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
206             return ret;
207         }
208     }
209 }