e9b59fd9df0ae6a03820cdd100f838cdd4f94fd8
[platform/core/csapi/tizenfx.git] / src / ElmSharp / ElmSharp / Image.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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.IO;
19 using System.Threading;
20 using System.Threading.Tasks;
21
22 namespace ElmSharp
23 {
24     public class Image : Widget
25     {
26         bool _canScaleUp = true;
27         bool _canScaleDown = true;
28         Interop.SmartEvent _clicked;
29
30         public Image(EvasObject parent) : base(parent)
31         {
32             _clicked = new Interop.SmartEvent(this, Handle, "clicked");
33             _clicked.On += (s, e) => Clicked?.Invoke(this, EventArgs.Empty);
34         }
35
36         public event EventHandler Clicked;
37         public event EventHandler LoadingCompleted;
38         public event EventHandler LoadingFailed;
39
40         public string File
41         {
42             get
43             {
44                 return Interop.Elementary.elm_image_file_get(Handle);
45             }
46         }
47
48         public bool IsSmooth
49         {
50             get
51             {
52                 return Interop.Elementary.elm_image_smooth_get(Handle);
53             }
54             set
55             {
56                 Interop.Elementary.elm_image_smooth_set(Handle, value);
57             }
58         }
59
60         public bool IsScaling
61         {
62             get
63             {
64                 return !Interop.Elementary.elm_image_no_scale_get(Handle);
65             }
66             set
67             {
68                 Interop.Elementary.elm_image_no_scale_set(Handle, !value);
69             }
70         }
71
72         public bool CanScaleDown
73         {
74             get
75             {
76                 return _canScaleDown;
77             }
78             set
79             {
80                 _canScaleDown = value;
81                 Interop.Elementary.elm_image_resizable_set(Handle, _canScaleUp, _canScaleDown);
82             }
83         }
84
85         public bool CanScaleUp
86         {
87             get
88             {
89                 return _canScaleUp;
90             }
91             set
92             {
93                 _canScaleUp = value;
94                 Interop.Elementary.elm_image_resizable_set(Handle, _canScaleUp, _canScaleDown);
95             }
96         }
97
98         public bool CanFillOutside
99         {
100             get
101             {
102                 return Interop.Elementary.elm_image_fill_outside_get(Handle);
103             }
104             set
105             {
106                 Interop.Elementary.elm_image_fill_outside_set(Handle, value);
107             }
108         }
109
110         public int PrescaleSize
111         {
112             get
113             {
114                 return Interop.Elementary.elm_image_prescale_get(Handle);
115             }
116             set
117             {
118                 Interop.Elementary.elm_image_prescale_set(Handle, value);
119             }
120         }
121
122         public bool IsFixedAspect
123         {
124             get
125             {
126                 return Interop.Elementary.elm_image_aspect_fixed_get(Handle);
127             }
128             set
129             {
130                 Interop.Elementary.elm_image_aspect_fixed_set(Handle, value);
131             }
132         }
133
134         public bool IsAnimated
135         {
136             get
137             {
138                 return Interop.Elementary.elm_image_animated_get(Handle);
139             }
140             set
141             {
142                 Interop.Elementary.elm_image_animated_set(Handle, value);
143             }
144         }
145
146         public bool IsAnimatedAvailable
147         {
148             get
149             {
150                 return Interop.Elementary.elm_image_animated_available_get(Handle);
151             }
152         }
153
154         public bool IsAnimationPlaying
155         {
156             get
157             {
158                 return Interop.Elementary.elm_image_animated_play_get(Handle);
159             }
160             set
161             {
162                 Interop.Elementary.elm_image_animated_play_set(Handle, value);
163             }
164         }
165
166         public bool IsEditable
167         {
168             get
169             {
170                 return Interop.Elementary.elm_image_editable_get(Handle);
171             }
172             set
173             {
174                 Interop.Elementary.elm_image_editable_set(Handle, value);
175             }
176         }
177
178         public Size ObjectSize
179         {
180             get
181             {
182                 int w, h;
183                 Interop.Elementary.elm_image_object_size_get(Handle, out w, out h);
184                 return new Size(w, h);
185             }
186         }
187
188         public bool IsOpaque
189         {
190             get
191             {
192                 IntPtr evasObj = Interop.Elementary.elm_image_object_get(Handle);
193                 if (evasObj != IntPtr.Zero)
194                 {
195                     return !Interop.Evas.evas_object_image_alpha_get(evasObj);
196                 }
197                 return false;
198             }
199             set
200             {
201                 IntPtr evasObj = Interop.Elementary.elm_image_object_get(Handle);
202                 if (evasObj != IntPtr.Zero)
203                 {
204                     Interop.Evas.evas_object_image_alpha_set(evasObj, !value);
205                 }
206             }
207         }
208
209         public ImageOrientation Orientation
210         {
211             get
212             {
213                 return (ImageOrientation)Interop.Elementary.elm_image_orient_get(Handle);
214             }
215             set
216             {
217                 Interop.Elementary.elm_image_orient_set(Handle, (int)value);
218             }
219         }
220
221         public override Color Color
222         {
223             get
224             {
225                 int r = 255, g = 255, b = 255, a = 255;
226                 IntPtr evasObj = Interop.Elementary.elm_image_object_get(Handle);
227                 if (evasObj != IntPtr.Zero)
228                 {
229                     Interop.Evas.evas_object_color_get(evasObj, out r, out g, out b, out a);
230                 }
231                 return Color.FromRgba(r, g, b, a);
232             }
233             set
234             {
235                 IntPtr evasObj = Interop.Elementary.elm_image_object_get(Handle);
236                 if (evasObj != IntPtr.Zero)
237                 {
238                     Interop.Evas.evas_object_color_set(evasObj, value.R, value.G, value.B, value.A);
239                 }
240             }
241         }
242
243         public bool Load(string file)
244         {
245             if (file == null)
246                 throw new ArgumentNullException("file");
247
248             Interop.Elementary.elm_image_async_open_set(Handle, false);
249             Interop.Elementary.elm_image_preload_disabled_set(Handle, true);
250             return Interop.Elementary.elm_image_file_set(Handle, file, null);
251         }
252
253         public bool Load(Uri uri)
254         {
255             if (uri == null)
256                 throw new ArgumentNullException("uri");
257
258             return Load(uri.IsFile ? uri.LocalPath : uri.AbsoluteUri);
259         }
260
261         [CLSCompliant(false)]
262         [Obsolete("This method will be removed. Use Load(Stream stream) instead.")]
263         public unsafe bool Load(byte* img, long size)
264         {
265             if (img == null)
266                 throw new ArgumentNullException("img");
267
268             Interop.Elementary.elm_image_async_open_set(Handle, false);
269             Interop.Elementary.elm_image_preload_disabled_set(Handle, true);
270             return Interop.Elementary.elm_image_memfile_set(Handle, img, size, IntPtr.Zero, IntPtr.Zero);
271         }
272
273         public bool Load(Stream stream)
274         {
275             if (stream == null)
276                 throw new ArgumentNullException("stream");
277
278             Interop.Elementary.elm_image_async_open_set(Handle, false);
279             Interop.Elementary.elm_image_preload_disabled_set(Handle, true);
280             MemoryStream memstream = new MemoryStream();
281             stream.CopyTo(memstream);
282             unsafe
283             {
284                 byte[] dataArr = memstream.ToArray();
285                 fixed (byte* data = &dataArr[0])
286                 {
287                     return Interop.Elementary.elm_image_memfile_set(Handle, data, dataArr.Length, IntPtr.Zero, IntPtr.Zero);
288                 }
289             }
290         }
291
292         public Task<bool> LoadAsync(string file, CancellationToken cancellationToken = default(CancellationToken))
293         {
294             if (file == null)
295                 throw new ArgumentNullException("file");
296
297             Interop.Elementary.elm_image_async_open_set(Handle, true);
298             Interop.Elementary.elm_image_preload_disabled_set(Handle, false);
299
300             var tcs = new TaskCompletionSource<bool>();
301
302             cancellationToken.Register(() =>
303             {
304                 if (tcs != null && !tcs.Task.IsCompleted)
305                 {
306                     tcs.SetCanceled();
307                 }
308             });
309
310             Interop.SmartEvent loadReady = new Interop.SmartEvent(this, Handle, "load,ready");
311             loadReady.On += (s, e) =>
312             {
313                 loadReady.Dispose();
314                 LoadingCompleted?.Invoke(this, EventArgs.Empty);
315                 if (tcs != null && !tcs.Task.IsCompleted)
316                 {
317                     tcs.SetResult(true);
318                 }
319             };
320
321             Interop.SmartEvent loadError = new Interop.SmartEvent(this, Handle, "load,error");
322             loadError.On += (s, e) =>
323             {
324                 loadError.Dispose();
325                 LoadingFailed?.Invoke(this, EventArgs.Empty);
326                 if (tcs != null && !tcs.Task.IsCompleted)
327                 {
328                     tcs.SetResult(false);
329                 }
330             };
331
332             bool ret = Interop.Elementary.elm_image_file_set(Handle, file, null);
333             if (!ret)
334             {
335                 throw new InvalidOperationException("Failed to set file to Image");
336             }
337
338             return tcs.Task;
339         }
340
341         public Task<bool> LoadAsync(Uri uri, CancellationToken cancellationToken = default(CancellationToken))
342         {
343             if (uri == null)
344                 throw new ArgumentNullException("uri");
345
346             return LoadAsync(uri.IsFile ? uri.LocalPath : uri.AbsoluteUri, cancellationToken);
347         }
348
349         public async Task<bool> LoadAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken))
350         {
351             if (stream == null)
352                 throw new ArgumentNullException("stream");
353
354             Interop.Elementary.elm_image_async_open_set(Handle, true);
355             Interop.Elementary.elm_image_preload_disabled_set(Handle, false);
356
357             var tcs = new TaskCompletionSource<bool>();
358
359             cancellationToken.Register(() =>
360             {
361                 if (tcs != null && !tcs.Task.IsCompleted)
362                 {
363                     tcs.SetCanceled();
364                 }
365             });
366
367             Interop.SmartEvent loadReady = new Interop.SmartEvent(this, Handle, "load,ready");
368             loadReady.On += (s, e) =>
369             {
370                 loadReady.Dispose();
371                 LoadingCompleted?.Invoke(this, EventArgs.Empty);
372                 if (tcs != null && !tcs.Task.IsCompleted)
373                 {
374                     tcs.SetResult(true);
375                 }
376             };
377
378             Interop.SmartEvent loadError = new Interop.SmartEvent(this, Handle, "load,error");
379             loadError.On += (s, e) =>
380             {
381                 loadError.Dispose();
382                 LoadingFailed?.Invoke(this, EventArgs.Empty);
383                 if (tcs != null && !tcs.Task.IsCompleted)
384                 {
385                     tcs.SetResult(false);
386                 }
387             };
388
389             MemoryStream memstream = new MemoryStream();
390             await stream.CopyToAsync(memstream);
391
392             unsafe
393             {
394                 byte[] dataArr = memstream.ToArray();
395                 fixed (byte* data = &dataArr[0])
396                 {
397                     bool ret = Interop.Elementary.elm_image_memfile_set(Handle, data, dataArr.Length, IntPtr.Zero, IntPtr.Zero);
398                     if (!ret)
399                     {
400                         return false;
401                     }
402                 }
403             }
404
405             return await tcs.Task;
406         }
407
408         protected override IntPtr CreateHandle(EvasObject parent)
409         {
410             return Interop.Elementary.elm_image_add(parent.Handle);
411         }
412     }
413
414     public enum ImageOrientation : int
415     {
416         None = 0,
417         Rotate90,
418         Rotate180,
419         Rotate270,
420         FlipHorizontal,
421         FlipVertical,
422         FlipTranspose,
423         FlipTransverse
424     }
425 }