[NUI] Fix to make null assigning to ResourceUrl possible (#538)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / BaseComponents / ImageView.cs
1 /*
2  * Copyright(c) 2018 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.Runtime.InteropServices;
19 using System.ComponentModel;
20 using Tizen.NUI.Binding;
21
22 namespace Tizen.NUI.BaseComponents
23 {
24
25     /// <summary>
26     /// ImageView is a class for displaying an image resource.<br />
27     /// An instance of ImageView can be created using a URL or an image instance.<br />
28     /// </summary>
29     /// <since_tizen> 3 </since_tizen>
30     public class ImageView : View
31     {
32         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
33         [EditorBrowsable(EditorBrowsableState.Never)]
34         public static readonly BindableProperty ResourceUrlProperty = BindableProperty.Create(nameof(ImageView.ResourceUrl), typeof(string), typeof(ImageView), string.Empty, propertyChanged: (bindable, oldValue, newValue) =>
35         {
36             var imageView = (ImageView)bindable;
37             imageView._url = (string)newValue;
38
39             if (imageView._url != null)
40             {
41                 if (imageView.IsCreateByXaml && imageView._url.Contains("*Resource*"))
42                 {
43                     string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
44                     imageView._url = imageView._url.Replace("*Resource*", resource);
45                 }
46             }
47             imageView.UpdateImage();
48         },
49         defaultValueCreator:(bindable) =>
50         {
51             var imageView = (ImageView)bindable;
52             if(imageView._url != null)
53             {
54                 Tizen.NUI.Object.GetProperty(imageView.swigCPtr, ImageView.Property.IMAGE).Get(out imageView._url);
55             }
56             return imageView._url;
57         });
58         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
59         [EditorBrowsable(EditorBrowsableState.Never)]
60         public static readonly BindableProperty ImageProperty = BindableProperty.Create("Image", typeof(PropertyMap), typeof(ImageView), new PropertyMap(), propertyChanged: (bindable, oldValue, newValue) =>
61         {
62             var imageView = (ImageView)bindable;
63             if (newValue != null)
64             {
65                 PropertyMap map = (PropertyMap)newValue;
66                 if (imageView.IsCreateByXaml)
67                 {
68                     string url = "", alphaMaskURL="", auxiliaryImageURL = "";
69                     string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
70                     PropertyValue urlValue = map.Find(NDalic.IMAGE_VISUAL_URL);
71                     bool ret = false;
72                     if (urlValue != null) ret = urlValue.Get(out url);
73                     PropertyMap mmap = new PropertyMap();
74                     if (ret && url.Contains("*Resource*"))
75                     {
76                         url = url.Replace("*Resource*", resource);
77                         mmap.Insert(NDalic.IMAGE_VISUAL_URL, new PropertyValue(url));
78                     }
79
80                     ret = false;
81                     PropertyValue alphaMaskUrlValue = map.Find(NDalic.IMAGE_VISUAL_ALPHA_MASK_URL);
82                     if (alphaMaskUrlValue != null) ret = alphaMaskUrlValue.Get(out alphaMaskURL);
83                     if (ret && alphaMaskURL.Contains("*Resource*"))
84                     {
85                         alphaMaskURL = alphaMaskURL.Replace("*Resource*", resource);
86                         mmap.Insert(NDalic.IMAGE_VISUAL_URL, new PropertyValue(alphaMaskURL));
87                     }
88
89                     ret = false;
90                     PropertyValue auxiliaryImageURLValue  = map.Find(NDalic.IMAGE_VISUAL_AUXILIARY_IMAGE_URL);
91                     if (auxiliaryImageURLValue != null) ret = auxiliaryImageURLValue.Get(out auxiliaryImageURL);
92                     if (ret && auxiliaryImageURL.Contains("*Resource*"))
93                     {
94                         auxiliaryImageURL = auxiliaryImageURL.Replace("*Resource*", resource);
95                         mmap.Insert(NDalic.IMAGE_VISUAL_AUXILIARY_IMAGE_URL, new PropertyValue(auxiliaryImageURL));
96                     }
97
98                     map.Merge(mmap);
99                 }
100                 if (imageView._border == null)
101                 {
102                     Tizen.NUI.Object.SetProperty(imageView.swigCPtr, ImageView.Property.IMAGE, new Tizen.NUI.PropertyValue(map));
103                 }
104             }
105         },
106         defaultValueCreator:(bindable) =>
107         {
108             var imageView = (ImageView)bindable;
109             if (imageView._border == null)
110             {
111                 PropertyMap temp = new PropertyMap();
112                 Tizen.NUI.Object.GetProperty(imageView.swigCPtr, ImageView.Property.IMAGE).Get(temp);
113                 return temp;
114             }
115             else
116             {
117                 return null;
118             }
119         });
120         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
121         [EditorBrowsable(EditorBrowsableState.Never)]
122         public static readonly BindableProperty PreMultipliedAlphaProperty = BindableProperty.Create("PreMultipliedAlpha", typeof(bool), typeof(ImageView), false, propertyChanged: (bindable, oldValue, newValue) =>
123         {
124             var imageView = (ImageView)bindable;
125             if (newValue != null)
126             {
127                 Tizen.NUI.Object.SetProperty(imageView.swigCPtr, ImageView.Property.PRE_MULTIPLIED_ALPHA, new Tizen.NUI.PropertyValue((bool)newValue));
128             }
129         },
130         defaultValueCreator:(bindable) =>
131         {
132             var imageView = (ImageView)bindable;
133             bool temp = false;
134             Tizen.NUI.Object.GetProperty(imageView.swigCPtr, ImageView.Property.PRE_MULTIPLIED_ALPHA).Get(out temp);
135             return temp;
136         });
137         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
138         [EditorBrowsable(EditorBrowsableState.Never)]
139         public static readonly BindableProperty PixelAreaProperty = BindableProperty.Create("PixelArea", typeof(RelativeVector4), typeof(ImageView), new RelativeVector4(0,0,0,0), propertyChanged: (bindable, oldValue, newValue) =>
140         {
141             var imageView = (ImageView)bindable;
142             if (newValue != null)
143             {
144                 Tizen.NUI.Object.SetProperty(imageView.swigCPtr, ImageView.Property.PIXEL_AREA, new Tizen.NUI.PropertyValue((RelativeVector4)newValue));
145             }
146         },
147         defaultValueCreator:(bindable) =>
148         {
149             var imageView = (ImageView)bindable;
150             Vector4 temp = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);
151             Tizen.NUI.Object.GetProperty(imageView.swigCPtr, ImageView.Property.PIXEL_AREA).Get(temp);
152             RelativeVector4 relativeTemp = new RelativeVector4(temp.X, temp.Y, temp.Z, temp.W);
153             return relativeTemp;
154         });
155         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
156         [EditorBrowsable(EditorBrowsableState.Never)]
157         public static readonly BindableProperty BorderProperty = BindableProperty.Create("Border", typeof(Rectangle), typeof(ImageView), new Rectangle(0,0,0,0), propertyChanged: (bindable, oldValue, newValue) =>
158         {
159             var imageView = (ImageView)bindable;
160             if (newValue != null)
161             {
162                 imageView._border = (Rectangle)newValue;
163                 imageView.UpdateImage();
164             }
165         },
166         defaultValueCreator:(bindable) =>
167         {
168             var imageView = (ImageView)bindable;
169             return imageView._border;
170         });
171         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
172         [EditorBrowsable(EditorBrowsableState.Never)]
173         public static readonly BindableProperty BorderOnlyProperty = BindableProperty.Create("BorderOnly", typeof(bool), typeof(ImageView), false, propertyChanged: (bindable, oldValue, newValue) =>
174         {
175             var imageView = (ImageView)bindable;
176             if (newValue != null)
177             {
178                 imageView._borderOnly = (bool)newValue;
179                 imageView.UpdateImage();
180             }
181         },
182         defaultValueCreator:(bindable) =>
183         {
184             var imageView = (ImageView)bindable;
185             return imageView._borderOnly ?? false;
186         });
187         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
188         [EditorBrowsable(EditorBrowsableState.Never)]
189         public static readonly BindableProperty SynchronosLoadingProperty = BindableProperty.Create("SynchronosLoading", typeof(bool), typeof(ImageView), false, propertyChanged: (bindable, oldValue, newValue) =>
190         {
191             var imageView = (ImageView)bindable;
192             if (newValue != null)
193             {
194                 imageView._synchronousLoading = (bool)newValue;
195                 imageView.UpdateImage();
196             }
197         },
198         defaultValueCreator:(bindable) =>
199         {
200             var imageView = (ImageView)bindable;
201             return imageView._synchronousLoading ?? false;
202         });
203         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
204         [EditorBrowsable(EditorBrowsableState.Never)]
205         public static readonly BindableProperty OrientationCorrectionProperty = BindableProperty.Create("OrientationCorrection", typeof(bool), typeof(ImageView), false, propertyChanged: (bindable, oldValue, newValue) =>
206         {
207             var imageView = (ImageView)bindable;
208             if (newValue != null)
209             {
210                 imageView._orientationCorrection = (bool)newValue;
211                 imageView.UpdateImage();
212             }
213         },
214         defaultValueCreator:(bindable) =>
215         {
216             var imageView = (ImageView)bindable;
217             return imageView._orientationCorrection ?? false;
218         });
219
220         private global::System.Runtime.InteropServices.HandleRef swigCPtr;
221
222         internal ImageView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(NDalicPINVOKE.ImageView_SWIGUpcast(cPtr), cMemoryOwn)
223         {
224             swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
225         }
226
227         internal static global::System.Runtime.InteropServices.HandleRef getCPtr(ImageView obj)
228         {
229             return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
230         }
231
232
233         /// <summary>
234         /// Event arguments of resource ready.
235         /// </summary>
236         /// <since_tizen> 3 </since_tizen>
237         public class ResourceReadyEventArgs : EventArgs
238         {
239             private View _view;
240
241             /// <summary>
242             /// The view whose resource is ready.
243             /// </summary>
244             /// <since_tizen> 3 </since_tizen>
245             public View View
246             {
247                 get
248                 {
249                     return _view;
250                 }
251                 set
252                 {
253                     _view = value;
254                 }
255             }
256         }
257
258         private EventHandler<ResourceReadyEventArgs> _resourceReadyEventHandler;
259         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
260         private delegate void ResourceReadyEventCallbackType(IntPtr data);
261         private ResourceReadyEventCallbackType _resourceReadyEventCallback;
262
263         /// <summary>
264         /// An event for ResourceReady signal which can be used to subscribe or unsubscribe the event handler.<br />
265         /// This signal is emitted after all resources required by a control are loaded and ready.<br />
266         /// Most resources are only loaded when the control is placed on the stage.<br />
267         /// </summary>
268         /// <since_tizen> 3 </since_tizen>
269         public event EventHandler<ResourceReadyEventArgs> ResourceReady
270         {
271             add
272             {
273                 if (_resourceReadyEventHandler == null)
274                 {
275                     _resourceReadyEventCallback = OnResourceReady;
276                     ResourceReadySignal(this).Connect(_resourceReadyEventCallback);
277                 }
278
279                 _resourceReadyEventHandler += value;
280             }
281
282             remove
283             {
284                 _resourceReadyEventHandler -= value;
285
286                 if (_resourceReadyEventHandler == null && ResourceReadySignal(this).Empty() == false)
287                 {
288                     ResourceReadySignal(this).Disconnect(_resourceReadyEventCallback);
289                 }
290             }
291         }
292
293         // Callback for View ResourceReady signal
294         private void OnResourceReady(IntPtr data)
295         {
296             ResourceReadyEventArgs e = new ResourceReadyEventArgs();
297             if (data != null)
298             {
299                 e.View = Registry.GetManagedBaseHandleFromNativePtr(data) as View;
300             }
301
302             if (_resourceReadyEventHandler != null)
303             {
304                 _resourceReadyEventHandler(this, e);
305             }
306         }
307
308         /// <summary>
309         /// you can override it to clean-up your own resources.
310         /// </summary>
311         /// <param name="type">DisposeTypes</param>
312         /// <since_tizen> 3 </since_tizen>
313         protected override void Dispose(DisposeTypes type)
314         {
315             if (disposed)
316             {
317                 return;
318             }
319
320             if (type == DisposeTypes.Explicit)
321             {
322                 //Called by User
323                 //Release your own managed resources here.
324                 //You should release all of your own disposable objects here.
325                 _border?.Dispose();
326                 _border = null;
327                 _nPatchMap?.Dispose();
328                 _nPatchMap = null;
329             }
330
331             //Release your own unmanaged resources here.
332             //You should not access any managed member here except static instance.
333             //because the execution order of Finalizes is non-deterministic.
334
335             if (swigCPtr.Handle != global::System.IntPtr.Zero)
336             {
337                 if (swigCMemOwn)
338                 {
339                     swigCMemOwn = false;
340                     NDalicPINVOKE.delete_ImageView(swigCPtr);
341                 }
342                 swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
343             }
344
345             base.Dispose(type);
346         }
347
348         internal new class Property
349         {
350             internal static readonly int RESOURCE_URL = NDalicPINVOKE.ImageView_Property_RESOURCE_URL_get();
351             internal static readonly int IMAGE = NDalicPINVOKE.ImageView_Property_IMAGE_get();
352             internal static readonly int PRE_MULTIPLIED_ALPHA = NDalicPINVOKE.ImageView_Property_PRE_MULTIPLIED_ALPHA_get();
353             internal static readonly int PIXEL_AREA = NDalicPINVOKE.ImageView_Property_PIXEL_AREA_get();
354             internal static readonly int ACTION_RELOAD = NDalicManualPINVOKE.ImageView_IMAGE_VISUAL_ACTION_RELOAD_get();
355             internal static readonly int ACTION_PLAY = NDalicManualPINVOKE.ImageView_IMAGE_VISUAL_ACTION_PLAY_get();
356             internal static readonly int ACTION_PAUSE = NDalicManualPINVOKE.ImageView_IMAGE_VISUAL_ACTION_PAUSE_get();
357             internal static readonly int ACTION_STOP = NDalicManualPINVOKE.ImageView_IMAGE_VISUAL_ACTION_STOP_get();
358         }
359
360         /// <summary>
361         /// Creates an initialized ImageView.
362         /// </summary>
363         /// <since_tizen> 3 </since_tizen>
364         public ImageView() : this(NDalicPINVOKE.ImageView_New__SWIG_0(), true)
365         {
366             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
367         }
368
369         /// <summary>
370         /// Creates an initialized ImageView from a URL to an image resource.<br />
371         /// If the string is empty, ImageView will not display anything.<br />
372         /// </summary>
373         /// <param name="url">The URL of the image resource to display.</param>
374         /// <since_tizen> 3 </since_tizen>
375         public ImageView(string url) : this(NDalicPINVOKE.ImageView_New__SWIG_2(url), true)
376         {
377             _url = url;
378             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
379
380         }
381         internal ImageView(string url, Uint16Pair size) : this(NDalicPINVOKE.ImageView_New__SWIG_3(url, Uint16Pair.getCPtr(size)), true)
382         {
383             _url = url;
384             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
385
386         }
387
388         /// <summary>
389         /// Downcasts a handle to imageView handle.
390         /// </summary>
391         /// Please do not use! this will be deprecated!
392         /// Instead please use as keyword.
393         /// <since_tizen> 3 </since_tizen>
394         [Obsolete("Please do not use! This will be deprecated! Please use as keyword instead! " +
395             "Like: " +
396             "BaseHandle handle = new ImageView(imagePath); " +
397             "ImageView image = handle as ImageView")]
398         [EditorBrowsable(EditorBrowsableState.Never)]
399         public static ImageView DownCast(BaseHandle handle)
400         {
401             ImageView ret = Registry.GetManagedBaseHandleFromNativePtr(handle) as ImageView;
402             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
403             return ret;
404         }
405
406         /// <summary>
407         /// Sets this ImageView from the given URL.<br />
408         /// If the URL is empty, ImageView will not display anything.<br />
409         /// </summary>
410         /// <param name="url">The URL to the image resource to display.</param>
411         /// <since_tizen> 3 </since_tizen>
412         public void SetImage(string url)
413         {
414             _url = url;
415             NDalicPINVOKE.ImageView_SetImage__SWIG_1(swigCPtr, url);
416             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
417         }
418         internal void SetImage(string url, Uint16Pair size)
419         {
420             _url = url;
421             NDalicPINVOKE.ImageView_SetImage__SWIG_2(swigCPtr, url, Uint16Pair.getCPtr(size));
422             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
423         }
424
425         internal ViewResourceReadySignal ResourceReadySignal(View view)
426         {
427             ViewResourceReadySignal ret = new ViewResourceReadySignal(NDalicPINVOKE.ResourceReadySignal(View.getCPtr(view)), false);
428             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
429             return ret;
430         }
431
432         /// <summary>
433         /// Queries if all resources required by a control are loaded and ready.<br />
434         /// Most resources are only loaded when the control is placed on the stage.<br />
435         /// True if the resources are loaded and ready, false otherwise.<br />
436         /// </summary>
437         /// <since_tizen> 3 </since_tizen>
438         public new bool IsResourceReady()
439         {
440             bool ret = NDalicPINVOKE.IsResourceReady(swigCPtr);
441             if (NDalicPINVOKE.SWIGPendingException.Pending)
442                 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
443             return ret;
444         }
445
446         /// <summary>
447         /// Forcefully reloads the image. All the visuals using this image will reload to the latest image.
448         /// </summary>
449         /// <since_tizen> 5 </since_tizen>        
450         public void Reload()
451         {
452             this.DoAction(ImageView.Property.IMAGE, Property.ACTION_RELOAD, new PropertyValue(0));
453         }
454
455         /// <summary>
456         /// Plays the animated GIF. This is also the default playback mode.
457         /// </summary>
458         /// <since_tizen> 5 </since_tizen>
459         public void Play()
460         {
461             this.DoAction(ImageView.Property.IMAGE, Property.ACTION_PLAY, new PropertyValue(0));
462         }
463
464         /// <summary>
465         /// Pauses the animated GIF.
466         /// </summary>
467         /// <since_tizen> 5 </since_tizen>
468         public void Pause()
469         {
470             this.DoAction(ImageView.Property.IMAGE, Property.ACTION_PAUSE, new PropertyValue(0));
471         }
472
473         /// <summary>
474         /// Stops the animated GIF.
475         /// </summary>
476         /// <since_tizen> 5 </since_tizen>
477         public void Stop()
478         {
479             this.DoAction(ImageView.Property.IMAGE, Property.ACTION_STOP, new PropertyValue(0));
480         }
481
482         /// <summary>
483         /// ImageView ResourceUrl, type string.
484         /// </summary>
485         /// <since_tizen> 3 </since_tizen>
486         public string ResourceUrl
487         {
488             get
489             {
490                 return (string)GetValue(ResourceUrlProperty);
491             }
492             set
493             {
494                 SetValue(ResourceUrlProperty, value);
495                 NotifyPropertyChanged();
496             }
497         }
498
499         /// <summary>
500         /// This will be deprecated, please use Image instead. <br />
501         /// ImageView ImageMap, type PropertyMap: string if it is a URL, map otherwise.
502         /// </summary>
503         /// <since_tizen> 3 </since_tizen>
504         [Obsolete("Please do not use! This will be deprecated! Please use Image property instead!")]
505         [EditorBrowsable(EditorBrowsableState.Never)]
506         public PropertyMap ImageMap
507         {
508             get
509             {
510                 if (_border == null)
511                 {
512                     PropertyMap temp = new PropertyMap();
513                     GetProperty(ImageView.Property.IMAGE).Get(temp);
514                     return temp;
515                 }
516                 else
517                 {
518                     return null;
519                 }
520             }
521             set
522             {
523                 if (_border == null)
524                 {
525                     if (_url != null) { value.Add("url", new PropertyValue(_url)); }
526                     SetProperty(ImageView.Property.IMAGE, new Tizen.NUI.PropertyValue(value));
527                     NotifyPropertyChanged();
528                 }
529             }
530         }
531
532         /// <summary>
533         /// ImageView Image, type PropertyMap
534         /// </summary>
535         /// <since_tizen> 4 </since_tizen>
536         public PropertyMap Image
537         {
538             get
539             {
540                 if (_border == null)
541                 {
542                     return (PropertyMap)GetValue(ImageProperty);
543                 }
544                 else
545                 {
546                     return null;
547                 }
548             }
549             set
550             {
551                 if (_border == null)
552                 {
553                     SetValue(ImageProperty, value);
554                     NotifyPropertyChanged();
555                 }
556             }
557         }
558
559         /// <summary>
560         /// ImageView PreMultipliedAlpha, type Boolean.<br />
561         /// Image must be initialized.<br />
562         /// </summary>
563         /// <since_tizen> 3 </since_tizen>
564         public bool PreMultipliedAlpha
565         {
566             get
567             {
568                 return (bool)GetValue(PreMultipliedAlphaProperty);
569             }
570             set
571             {
572                 SetValue(PreMultipliedAlphaProperty, value);
573                 NotifyPropertyChanged();
574             }
575         }
576
577         /// <summary>
578         /// ImageView PixelArea, type Vector4 (Animatable property).<br />
579         /// Pixel area is a relative value with the whole image area as [0.0, 0.0, 1.0, 1.0].<br />
580         /// </summary>
581         /// <since_tizen> 3 </since_tizen>
582         public RelativeVector4 PixelArea
583         {
584             get
585             {
586                 return (RelativeVector4)GetValue(PixelAreaProperty);
587             }
588             set
589             {
590                 SetValue(PixelAreaProperty, value);
591                 NotifyPropertyChanged();
592             }
593         }
594
595         /// <summary>
596         /// The border of the image in the order: left, right, bottom, top.<br />
597         /// If set, ImageMap will be ignored.<br />
598         /// For N-Patch images only.<br />
599         /// Optional.
600         /// </summary>
601         /// <since_tizen> 3 </since_tizen>
602         public Rectangle Border
603         {
604             get
605             {
606                 return (Rectangle)GetValue(BorderProperty);
607             }
608             set
609             {
610                 SetValue(BorderProperty, value);
611                 NotifyPropertyChanged();
612             }
613         }
614
615         /// <summary>
616         /// Gets or sets whether to draw the borders only (if true).<br />
617         /// If not specified, the default is false.<br />
618         /// For N-Patch images only.<br />
619         /// Optional.
620         /// </summary>
621         /// <since_tizen> 3 </since_tizen>
622         public bool BorderOnly
623         {
624             get
625             {
626                 return (bool)GetValue(BorderOnlyProperty);
627             }
628             set
629             {
630                 SetValue(BorderOnlyProperty, value);
631                 NotifyPropertyChanged();
632             }
633         }
634
635         /// <summary>
636         /// Gets or sets whether to synchronos loading the resourceurl of image.<br />
637         /// </summary>
638         /// <since_tizen> 3 </since_tizen>
639         public bool SynchronosLoading
640         {
641             get
642             {
643                 return (bool)GetValue(SynchronosLoadingProperty);
644             }
645             set
646             {
647                 SetValue(SynchronosLoadingProperty, value);
648                 NotifyPropertyChanged();
649             }
650         }
651
652         /// <summary>
653         /// Gets or sets whether to automatically correct the orientation of an image.<br />
654         /// </summary>
655         /// <since_tizen> 5 </since_tizen>
656         public bool OrientationCorrection
657         {
658             get
659             {
660                 return (bool)GetValue(OrientationCorrectionProperty);
661             }
662             set
663             {
664                 SetValue(OrientationCorrectionProperty, value);
665                 NotifyPropertyChanged();
666             }
667         }
668
669
670         /// <summary>
671         /// Gets the loading state of the visual resource.
672         /// </summary>
673         /// <since_tizen> 5 </since_tizen>
674         public ImageView.LoadingStatusType LoadingStatus
675         {
676             get
677             {
678                 return (ImageView.LoadingStatusType)NDalicManualPINVOKE.View_GetVisualResourceStatus(swigCPtr, (int)Property.IMAGE);
679             }
680         }
681
682         /// <summary>
683         /// Enumeration for LoadingStatus of image.
684         /// </summary>
685         /// <since_tizen> 5 </since_tizen>
686         public enum LoadingStatusType
687         {
688             /// <summary>
689             /// Loading preparing status.
690             /// </summary>
691             /// <since_tizen> 5 </since_tizen>
692             Preparing,
693             /// <summary>
694             /// Loading ready status.
695             /// </summary>
696             /// <since_tizen> 5 </since_tizen>
697             Ready,
698             /// <summary>
699             /// Loading failed status.
700             /// </summary>
701             /// <since_tizen> 5 </since_tizen>
702             Failed
703         }
704
705
706         private void UpdateImage()
707         {
708             if (_url != null)
709             {
710                 if (_border != null)
711                 { // for nine-patch image
712                     _nPatchMap = new PropertyMap();
713                     _nPatchMap.Add(Visual.Property.Type, new PropertyValue((int)Visual.Type.NPatch));
714                     _nPatchMap.Add(NpatchImageVisualProperty.URL, new PropertyValue(_url));
715                     _nPatchMap.Add(NpatchImageVisualProperty.Border, new PropertyValue(_border));
716                     if (_borderOnly != null) { _nPatchMap.Add(NpatchImageVisualProperty.BorderOnly, new PropertyValue((bool)_borderOnly)); }
717                     if (_synchronousLoading != null) { _nPatchMap.Add(NpatchImageVisualProperty.SynchronousLoading, new PropertyValue((bool)_synchronousLoading)); }
718                     if (_orientationCorrection != null) { _nPatchMap.Add(ImageVisualProperty.OrientationCorrection, new PropertyValue((bool)_orientationCorrection)); }
719                     SetProperty(ImageView.Property.IMAGE, new PropertyValue(_nPatchMap));
720                 }
721                 else if (_synchronousLoading != null || _orientationCorrection != null)
722                 { // for normal image, with synchronous loading property
723                     PropertyMap imageMap = new PropertyMap();
724                     imageMap.Add(Visual.Property.Type, new PropertyValue((int)Visual.Type.Image));
725                     imageMap.Add(ImageVisualProperty.URL, new PropertyValue(_url));
726                     if (_synchronousLoading != null) { imageMap.Add(ImageVisualProperty.SynchronousLoading, new PropertyValue((bool)_synchronousLoading)); }
727                     if (_orientationCorrection != null) { imageMap.Add(ImageVisualProperty.OrientationCorrection, new PropertyValue((bool)_orientationCorrection)); }
728                     SetProperty(ImageView.Property.IMAGE, new PropertyValue(imageMap));
729                 }
730                 else
731                 { // just for normal image
732                     SetProperty(ImageView.Property.IMAGE, new PropertyValue(_url));
733                 }
734             }
735             else
736             {
737                 SetProperty(ImageView.Property.IMAGE, new PropertyValue(""));
738             }
739         }
740
741         private Rectangle _border = null;
742         private PropertyMap _nPatchMap = null;
743         private bool? _synchronousLoading = null;
744         private bool? _borderOnly = null;
745         private string _url = null;
746         private bool? _orientationCorrection = null;
747
748
749         internal class ResourceLoadedEventArgs : EventArgs
750         {
751             private ResourceLoadingStatusType status = ResourceLoadingStatusType.Invalid;
752             public ResourceLoadingStatusType Status
753             {
754                 get
755                 {
756                     return status;
757                 }
758                 set
759                 {
760                     status = value;
761                 }
762             }
763         }
764
765         private EventHandler<ResourceLoadedEventArgs> _resourceLoadedEventHandler;
766         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
767         private delegate void _resourceLoadedCallbackType(IntPtr view);
768         private _resourceLoadedCallbackType _resourceLoadedCallback;
769
770         internal event EventHandler<ResourceLoadedEventArgs> ResourceLoaded
771         {
772             add
773             {
774                 if (_resourceLoadedEventHandler == null)
775                 {
776                     _resourceLoadedCallback = OnResourceLoaded;
777                     this.ResourceReadySignal(this).Connect(_resourceLoadedCallback);
778                 }
779
780                 _resourceLoadedEventHandler += value;
781             }
782             remove
783             {
784                 _resourceLoadedEventHandler -= value;
785
786                 if (_resourceLoadedEventHandler == null && this.ResourceReadySignal(this).Empty() == false)
787                 {
788                     this.ResourceReadySignal(this).Disconnect(_resourceLoadedCallback);
789                 }
790             }
791         }
792
793         private void OnResourceLoaded(IntPtr view)
794         {
795             ResourceLoadedEventArgs e = new ResourceLoadedEventArgs();
796             e.Status = (ResourceLoadingStatusType)NDalicManualPINVOKE.View_GetVisualResourceStatus(this.swigCPtr, Property.IMAGE);
797
798             if (_resourceLoadedEventHandler != null)
799             {
800                 _resourceLoadedEventHandler(this, e);
801             }
802         }
803
804         internal ResourceLoadingStatusType GetResourceStatus()
805         {
806             return (ResourceLoadingStatusType)NDalicManualPINVOKE.View_GetVisualResourceStatus(this.swigCPtr, Property.IMAGE);
807         }
808
809
810     }
811
812 }