[NUI] Fix ImageView Dispose crash (#2933)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / BaseComponents / ImageView.cs
1 /*
2 * Copyright(c) 2019 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         static ImageView() { }
33
34         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
35         [EditorBrowsable(EditorBrowsableState.Never)]
36         public static readonly BindableProperty ResourceUrlProperty = BindableProperty.Create(nameof(ImageView.ResourceUrl), typeof(string), typeof(ImageView), string.Empty, propertyChanged: (bindable, oldValue, newValue) =>
37         {
38             var imageView = (ImageView)bindable;
39
40             if (newValue is Selector<string> selector)
41             {
42                 imageView.ResourceUrlSelector = selector;
43             }
44             else
45             {
46                 imageView.resourceUrlSelector?.Reset(imageView);
47                 imageView.SetResourceUrl((string)newValue);
48             }
49         },
50         defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
51         {
52             var imageView = (ImageView)bindable;
53             string ret = "";
54
55             PropertyMap imageMap = new PropertyMap();
56             Tizen.NUI.Object.GetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.IMAGE).Get(imageMap);
57             imageMap.Find(ImageVisualProperty.URL)?.Get(out ret);
58             return ret;
59         }));
60
61         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
62         [EditorBrowsable(EditorBrowsableState.Never)]
63         public static readonly BindableProperty ImageProperty = BindableProperty.Create(nameof(ImageView.Image), typeof(PropertyMap), typeof(ImageView), null, propertyChanged: (BindableProperty.BindingPropertyChangedDelegate)((bindable, oldValue, newValue) =>
64         {
65             var imageView = (ImageView)bindable;
66             if (newValue != null)
67             {
68                 PropertyMap map = (PropertyMap)newValue;
69                 if (imageView.IsCreateByXaml)
70                 {
71                     string url = "", alphaMaskURL = "", auxiliaryImageURL = "";
72                     string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
73                     PropertyValue urlValue = map.Find(NDalic.ImageVisualUrl);
74                     bool ret = false;
75                     if (urlValue != null) ret = urlValue.Get(out url);
76                     PropertyMap mmap = new PropertyMap();
77                     if (ret && url.StartsWith("*Resource*"))
78                     {
79                         url = url.Replace("*Resource*", resource);
80                         mmap.Insert(NDalic.ImageVisualUrl, new PropertyValue(url));
81                     }
82
83                     ret = false;
84                     PropertyValue alphaMaskUrlValue = map.Find(NDalic.ImageVisualAlphaMaskUrl);
85                     if (alphaMaskUrlValue != null) ret = alphaMaskUrlValue.Get(out alphaMaskURL);
86                     if (ret && alphaMaskURL.StartsWith("*Resource*"))
87                     {
88                         alphaMaskURL = alphaMaskURL.Replace("*Resource*", resource);
89                         mmap.Insert(NDalic.ImageVisualUrl, new PropertyValue(alphaMaskURL));
90                     }
91
92                     ret = false;
93                     PropertyValue auxiliaryImageURLValue = map.Find(NDalic.ImageVisualAuxiliaryImageUrl);
94                     if (auxiliaryImageURLValue != null) ret = auxiliaryImageURLValue.Get(out auxiliaryImageURL);
95                     if (ret && auxiliaryImageURL.StartsWith("*Resource*"))
96                     {
97                         auxiliaryImageURL = auxiliaryImageURL.Replace("*Resource*", resource);
98                         mmap.Insert(NDalic.ImageVisualAuxiliaryImageUrl, new PropertyValue(auxiliaryImageURL));
99                     }
100
101                     map.Merge(mmap);
102                 }
103                 if (imageView._border == null)
104                 {
105                     Tizen.NUI.Object.SetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.IMAGE, new Tizen.NUI.PropertyValue(map));
106                 }
107             }
108         }),
109         defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
110         {
111             var imageView = (ImageView)bindable;
112             if (imageView._border == null)
113             {
114                 PropertyMap temp = new PropertyMap();
115                 Tizen.NUI.Object.GetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.IMAGE).Get(temp);
116                 return temp;
117             }
118             else
119             {
120                 return null;
121             }
122         }));
123
124         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
125         [EditorBrowsable(EditorBrowsableState.Never)]
126         public static readonly BindableProperty PreMultipliedAlphaProperty = BindableProperty.Create(nameof(PreMultipliedAlpha), typeof(bool), typeof(ImageView), false, propertyChanged: (BindableProperty.BindingPropertyChangedDelegate)((bindable, oldValue, newValue) =>
127         {
128             var imageView = (ImageView)bindable;
129             if (newValue != null)
130             {
131                 Tizen.NUI.Object.SetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.PreMultipliedAlpha, new Tizen.NUI.PropertyValue((bool)newValue));
132             }
133         }),
134         defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
135         {
136             var imageView = (ImageView)bindable;
137             bool temp = false;
138             Tizen.NUI.Object.GetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.PreMultipliedAlpha).Get(out temp);
139             return temp;
140         }));
141
142         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
143         [EditorBrowsable(EditorBrowsableState.Never)]
144         public static readonly BindableProperty PixelAreaProperty = BindableProperty.Create(nameof(PixelArea), typeof(RelativeVector4), typeof(ImageView), null, propertyChanged: (BindableProperty.BindingPropertyChangedDelegate)((bindable, oldValue, newValue) =>
145         {
146             var imageView = (ImageView)bindable;
147             if (newValue != null)
148             {
149                 Tizen.NUI.Object.SetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.PixelArea, new Tizen.NUI.PropertyValue((RelativeVector4)newValue));
150             }
151         }),
152         defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
153         {
154             var imageView = (ImageView)bindable;
155             Vector4 temp = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);
156             Tizen.NUI.Object.GetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.PixelArea).Get(temp);
157             RelativeVector4 relativeTemp = new RelativeVector4(temp.X, temp.Y, temp.Z, temp.W);
158             return relativeTemp;
159         }));
160
161         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
162         [EditorBrowsable(EditorBrowsableState.Never)]
163         public static readonly BindableProperty BorderProperty = BindableProperty.Create(nameof(Border), typeof(Rectangle), typeof(ImageView), null, propertyChanged: (bindable, oldValue, newValue) =>
164         {
165             var imageView = (ImageView)bindable;
166             imageView.borderSelector?.Reset(imageView);
167
168             if (newValue is Selector<Rectangle> selector)
169             {
170                 if (selector.HasAll()) imageView.SetBorder(selector.All);
171                 else imageView.borderSelector = new TriggerableSelector<Rectangle>(imageView, selector, imageView.SetBorder, true);
172             }
173             else
174             {
175                 imageView.SetBorder((Rectangle)newValue);
176             }
177         },
178         defaultValueCreator: (bindable) =>
179         {
180             var imageView = (ImageView)bindable;
181             return imageView._border;
182         });
183
184         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
185         [EditorBrowsable(EditorBrowsableState.Never)]
186         public static readonly BindableProperty BorderOnlyProperty = BindableProperty.Create(nameof(BorderOnly), typeof(bool), typeof(ImageView), false, propertyChanged: (bindable, oldValue, newValue) =>
187         {
188             var imageView = (ImageView)bindable;
189             if (newValue != null)
190             {
191                 imageView.UpdateImage(NpatchImageVisualProperty.BorderOnly, new PropertyValue((bool)newValue));
192             }
193         },
194         defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
195         {
196             var imageView = (ImageView)bindable;
197             bool ret = false;
198             PropertyMap imageMap = new PropertyMap();
199             Tizen.NUI.Object.GetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.IMAGE).Get(imageMap);
200             imageMap.Find(ImageVisualProperty.BorderOnly)?.Get(out ret);
201             return ret;
202         }));
203
204         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
205         [EditorBrowsable(EditorBrowsableState.Never)]
206         public static readonly BindableProperty SynchronosLoadingProperty = BindableProperty.Create(nameof(SynchronosLoading), typeof(bool), typeof(ImageView), false, propertyChanged: (bindable, oldValue, newValue) =>
207         {
208             var imageView = (ImageView)bindable;
209             if (newValue != null)
210             {
211                 imageView._synchronosLoading = (bool)newValue;
212                 imageView.UpdateImage(NpatchImageVisualProperty.SynchronousLoading, new PropertyValue((bool)newValue));
213             }
214         },
215         defaultValueCreator: (bindable) =>
216         {
217             var imageView = (ImageView)bindable;
218             return imageView._synchronosLoading;
219         });
220
221         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
222         [EditorBrowsable(EditorBrowsableState.Never)]
223         public static readonly BindableProperty OrientationCorrectionProperty = BindableProperty.Create(nameof(OrientationCorrection), typeof(bool), typeof(ImageView), false, propertyChanged: (bindable, oldValue, newValue) =>
224         {
225             var imageView = (ImageView)bindable;
226             if (newValue != null)
227             {
228                 imageView.UpdateImage(ImageVisualProperty.OrientationCorrection, new PropertyValue((bool)newValue));
229             }
230         },
231         defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
232         {
233             var imageView = (ImageView)bindable;
234
235             bool ret = false;
236             PropertyMap imageMap = new PropertyMap();
237             Tizen.NUI.Object.GetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.IMAGE).Get(imageMap);
238             imageMap?.Find(ImageVisualProperty.OrientationCorrection)?.Get(out ret);
239
240             return ret;
241         }));
242
243         private EventHandler<ResourceReadyEventArgs> _resourceReadyEventHandler;
244         private ResourceReadyEventCallbackType _resourceReadyEventCallback;
245         private EventHandler<ResourceLoadedEventArgs> _resourceLoadedEventHandler;
246         private _resourceLoadedCallbackType _resourceLoadedCallback;
247
248         private Rectangle _border;
249         private string _resourceUrl = "";
250         private bool _synchronosLoading = false;
251         private string _alphaMaskUrl = null;
252         private int _desired_width = -1;
253         private int _desired_height = -1;
254         private VisualFittingModeType _fittingMode = VisualFittingModeType.Fill;
255         private TriggerableSelector<string> resourceUrlSelector;
256         private TriggerableSelector<Rectangle> borderSelector;
257
258         /// <summary>
259         /// Creates an initialized ImageView.
260         /// </summary>
261         /// <since_tizen> 3 </since_tizen>
262         public ImageView() : this(Interop.ImageView.New(), true)
263         {
264             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
265         }
266
267         /// This will be public opened in next release of tizen after ACR done. Before ACR, it is used as HiddenAPI (InhouseAPI).
268         [EditorBrowsable(EditorBrowsableState.Never)]
269         public ImageView(ViewStyle viewStyle) : this(Interop.ImageView.New(), true, viewStyle)
270         {
271         }
272
273         /// <summary>
274         /// Creates an initialized ImageView with setting the status of shown or hidden.
275         /// </summary>
276         /// <param name="shown">false : Not displayed (hidden), true : displayed (shown)</param>
277         /// This will be public opened in next release of tizen after ACR done. Before ACR, it is used as HiddenAPI (InhouseAPI).
278         [EditorBrowsable(EditorBrowsableState.Never)]
279         public ImageView(bool shown) : this(Interop.ImageView.New(), true)
280         {
281             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
282             SetVisible(shown);
283         }
284
285         /// <summary>
286         /// Creates an initialized ImageView from a URL to an image resource.<br />
287         /// If the string is empty, ImageView will not display anything.<br />
288         /// </summary>
289         /// <param name="url">The URL of the image resource to display.</param>
290         /// <since_tizen> 3 </since_tizen>
291         public ImageView(string url) : this(Interop.ImageView.New(url), true)
292         {
293             ResourceUrl = url;
294             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
295
296         }
297
298         /// <summary>
299         /// Creates an initialized ImageView from a URL to an image resource with setting shown or hidden.
300         /// </summary>
301         /// <param name="url">The URL of the image resource to display.</param>
302         /// <param name="shown">false : Not displayed (hidden), true : displayed (shown)</param>
303         /// This will be public opened in next release of tizen after ACR done. Before ACR, it is used as HiddenAPI (InhouseAPI).
304         [EditorBrowsable(EditorBrowsableState.Never)]
305         public ImageView(string url, bool shown) : this(Interop.ImageView.New(url), true)
306         {
307             ResourceUrl = url;
308             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
309             SetVisible(shown);
310         }
311
312         internal ImageView(string url, Uint16Pair size, bool shown = true) : this(Interop.ImageView.New(url, Uint16Pair.getCPtr(size)), true)
313         {
314             ResourceUrl = url;
315             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
316
317             if (!shown)
318             {
319                 SetVisible(false);
320             }
321         }
322
323         internal ImageView(global::System.IntPtr cPtr, bool cMemoryOwn, ViewStyle viewStyle, bool shown = true) : base(cPtr, cMemoryOwn, viewStyle)
324         {
325             if (!shown)
326             {
327                 SetVisible(false);
328             }
329         }
330
331         internal ImageView(global::System.IntPtr cPtr, bool cMemoryOwn, bool shown = true) : base(cPtr, cMemoryOwn, null)
332         {
333             if (!shown)
334             {
335                 SetVisible(false);
336             }
337         }
338
339         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
340         private delegate void ResourceReadyEventCallbackType(IntPtr data);
341         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
342         private delegate void _resourceLoadedCallbackType(IntPtr view);
343
344         /// <summary>
345         /// An event for ResourceReady signal which can be used to subscribe or unsubscribe the event handler.<br />
346         /// This signal is emitted after all resources required by a control are loaded and ready.<br />
347         /// Most resources are only loaded when the control is placed on the stage.<br />
348         /// </summary>
349         /// <since_tizen> 3 </since_tizen>
350         public event EventHandler<ResourceReadyEventArgs> ResourceReady
351         {
352             add
353             {
354                 if (_resourceReadyEventHandler == null)
355                 {
356                     _resourceReadyEventCallback = OnResourceReady;
357                     ViewResourceReadySignal resourceReadySignal = ResourceReadySignal(this);
358                     resourceReadySignal?.Connect(_resourceReadyEventCallback);
359                     resourceReadySignal?.Dispose();
360                 }
361
362                 _resourceReadyEventHandler += value;
363             }
364
365             remove
366             {
367                 _resourceReadyEventHandler -= value;
368
369                 ViewResourceReadySignal resourceReadySignal = ResourceReadySignal(this);
370                 if (_resourceReadyEventHandler == null && resourceReadySignal?.Empty() == false)
371                 {
372                     resourceReadySignal?.Disconnect(_resourceReadyEventCallback);
373                 }
374                 resourceReadySignal?.Dispose();
375             }
376         }
377
378         internal event EventHandler<ResourceLoadedEventArgs> ResourceLoaded
379         {
380             add
381             {
382                 if (_resourceLoadedEventHandler == null)
383                 {
384                     _resourceLoadedCallback = OnResourceLoaded;
385                     ViewResourceReadySignal resourceReadySignal = this.ResourceReadySignal(this);
386                     resourceReadySignal?.Connect(_resourceLoadedCallback);
387                     resourceReadySignal?.Dispose();
388                 }
389
390                 _resourceLoadedEventHandler += value;
391             }
392             remove
393             {
394                 _resourceLoadedEventHandler -= value;
395                 ViewResourceReadySignal resourceReadySignal = this.ResourceReadySignal(this);
396                 if (_resourceLoadedEventHandler == null && resourceReadySignal?.Empty() == false)
397                 {
398                     resourceReadySignal?.Disconnect(_resourceLoadedCallback);
399                 }
400                 resourceReadySignal?.Dispose();
401             }
402         }
403
404         /// <summary>
405         /// Enumeration for LoadingStatus of image.
406         /// </summary>
407         /// <since_tizen> 5 </since_tizen>
408         public enum LoadingStatusType
409         {
410             /// <summary>
411             /// Loading preparing status.
412             /// </summary>
413             /// <since_tizen> 5 </since_tizen>
414             Preparing,
415             /// <summary>
416             /// Loading ready status.
417             /// </summary>
418             /// <since_tizen> 5 </since_tizen>
419             Ready,
420             /// <summary>
421             /// Loading failed status.
422             /// </summary>
423             /// <since_tizen> 5 </since_tizen>
424             Failed
425         }
426
427         /// <summary>
428         /// ImageView ResourceUrl, type string.
429         /// This is one of mandatory property. Even if not set or null set, it sets empty string ("") internally.
430         /// When it is set as null, it gives empty string ("") to be read.
431         /// </summary>
432         /// <since_tizen> 3 </since_tizen>
433         public string ResourceUrl
434         {
435             get
436             {
437                 return (string)GetValue(ResourceUrlProperty);
438             }
439             set
440             {
441                 SetValue(ResourceUrlProperty, value);
442                 NotifyPropertyChanged();
443             }
444         }
445
446         /// <summary>
447         /// This will be deprecated, please use Image instead. <br />
448         /// ImageView ImageMap, type PropertyMap: string if it is a URL, map otherwise.
449         /// </summary>
450         /// <since_tizen> 3 </since_tizen>
451         [Obsolete("Please do not use! This will be deprecated! Please use Image property instead!")]
452         [EditorBrowsable(EditorBrowsableState.Never)]
453         public PropertyMap ImageMap
454         {
455             get
456             {
457                 if (_border == null)
458                 {
459                     PropertyMap returnValue = new PropertyMap();
460                     PropertyValue image = GetProperty(ImageView.Property.IMAGE);
461                     image?.Get(returnValue);
462                     image?.Dispose();
463                     return returnValue;
464                 }
465                 else
466                 {
467                     return null;
468                 }
469             }
470             set
471             {
472                 if (_border == null)
473                 {
474                     PropertyValue setValue = new Tizen.NUI.PropertyValue(value);
475                     SetProperty(ImageView.Property.IMAGE, setValue);
476                     NotifyPropertyChanged();
477                     setValue?.Dispose();
478                 }
479             }
480         }
481
482         /// <summary>
483         /// ImageView Image, type PropertyMap
484         /// </summary>
485         /// <since_tizen> 4 </since_tizen>
486         public PropertyMap Image
487         {
488             get
489             {
490                 if (_border == null)
491                 {
492                     return (PropertyMap)GetValue(ImageProperty);
493                 }
494                 else
495                 {
496                     return null;
497                 }
498             }
499             set
500             {
501                 if (_border == null)
502                 {
503                     SetValue(ImageProperty, value);
504                     NotifyPropertyChanged();
505                 }
506             }
507         }
508
509         /// <summary>
510         /// ImageView PreMultipliedAlpha, type Boolean.<br />
511         /// Image must be initialized.<br />
512         /// </summary>
513         /// <since_tizen> 3 </since_tizen>
514         public bool PreMultipliedAlpha
515         {
516             get
517             {
518                 return (bool)GetValue(PreMultipliedAlphaProperty);
519             }
520             set
521             {
522                 SetValue(PreMultipliedAlphaProperty, value);
523                 NotifyPropertyChanged();
524             }
525         }
526
527         /// <summary>
528         /// ImageView PixelArea, type Vector4 (Animatable property).<br />
529         /// Pixel area is a relative value with the whole image area as [0.0, 0.0, 1.0, 1.0].<br />
530         /// </summary>
531         /// <remarks>
532         /// The property cascade chaining set is possible. For example, this (imageView.PixelArea.X = 0.1f;) is possible.
533         /// </remarks>
534         /// <since_tizen> 3 </since_tizen>
535         public RelativeVector4 PixelArea
536         {
537             get
538             {
539                 RelativeVector4 temp = (RelativeVector4)GetValue(PixelAreaProperty);
540                 return new RelativeVector4(OnPixelAreaChanged, temp.X, temp.Y, temp.Z, temp.W);
541             }
542             set
543             {
544                 SetValue(PixelAreaProperty, value);
545                 NotifyPropertyChanged();
546             }
547         }
548
549         /// <summary>
550         /// The border of the image in the order: left, right, bottom, top.<br />
551         /// If set, ImageMap will be ignored.<br />
552         /// For N-Patch images only.<br />
553         /// Optional.
554         /// </summary>
555         /// <remarks>
556         /// The property cascade chaining set is possible. For example, this (imageView.Border.X = 1;) is possible.
557         /// </remarks>
558         /// <since_tizen> 3 </since_tizen>
559         public Rectangle Border
560         {
561             get
562             {
563                 Rectangle temp = (Rectangle)GetValue(BorderProperty);
564                 if (null == temp)
565                 {
566                     return null;
567                 }
568                 else
569                 {
570                     return new Rectangle(OnBorderChanged, temp.X, temp.Y, temp.Width, temp.Height);
571                 }
572             }
573             set
574             {
575                 SetValue(BorderProperty, value);
576                 NotifyPropertyChanged();
577             }
578         }
579
580         /// <summary>
581         /// Gets or sets whether to draw the borders only (if true).<br />
582         /// If not specified, the default is false.<br />
583         /// For N-Patch images only.<br />
584         /// Optional.
585         /// </summary>
586         /// <since_tizen> 3 </since_tizen>
587         public bool BorderOnly
588         {
589             get
590             {
591                 return (bool)GetValue(BorderOnlyProperty);
592             }
593             set
594             {
595                 SetValue(BorderOnlyProperty, value);
596                 NotifyPropertyChanged();
597             }
598         }
599
600         /// <summary>
601         /// Gets or sets whether to synchronous loading the resourceurl of image.<br />
602         /// </summary>
603         /// <since_tizen> 3 </since_tizen>
604         public bool SynchronosLoading
605         {
606             get
607             {
608                 return (bool)GetValue(SynchronosLoadingProperty);
609             }
610             set
611             {
612                 SetValue(SynchronosLoadingProperty, value);
613                 NotifyPropertyChanged();
614             }
615         }
616
617         /// <summary>
618         /// Gets or sets whether to automatically correct the orientation of an image.<br />
619         /// </summary>
620         /// <since_tizen> 5 </since_tizen>
621         public bool OrientationCorrection
622         {
623             get
624             {
625                 return (bool)GetValue(OrientationCorrectionProperty);
626             }
627             set
628             {
629                 SetValue(OrientationCorrectionProperty, value);
630                 NotifyPropertyChanged();
631             }
632         }
633
634         /// <summary>
635         /// Gets the loading state of the visual resource.
636         /// </summary>
637         /// <since_tizen> 5 </since_tizen>
638         public ImageView.LoadingStatusType LoadingStatus
639         {
640             get
641             {
642                 return (ImageView.LoadingStatusType)Interop.View.GetVisualResourceStatus(SwigCPtr, (int)Property.IMAGE);
643             }
644         }
645
646         /// <summary>
647         /// Downcasts a handle to imageView handle.
648         /// </summary>
649         /// <exception cref="ArgumentNullException"> Thrown when handle is null. </exception>
650         /// Please do not use! this will be deprecated!
651         /// Instead please use as keyword.
652         /// <since_tizen> 3 </since_tizen>
653         [Obsolete("Please do not use! This will be deprecated! Please use as keyword instead! " +
654         "Like: " +
655         "BaseHandle handle = new ImageView(imagePath); " +
656         "ImageView image = handle as ImageView")]
657         [EditorBrowsable(EditorBrowsableState.Never)]
658         public static ImageView DownCast(BaseHandle handle)
659         {
660             if (null == handle)
661             {
662                 throw new ArgumentNullException(nameof(handle));
663             }
664             ImageView ret = Registry.GetManagedBaseHandleFromNativePtr(handle) as ImageView;
665             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
666             return ret;
667         }
668
669         /// <summary>
670         /// Sets this ImageView from the given URL.<br />
671         /// If the URL is empty, ImageView will not display anything.<br />
672         /// </summary>
673         /// <param name="url">The URL to the image resource to display.</param>
674         /// <exception cref="ArgumentNullException"> Thrown when url is null. </exception>
675         /// <since_tizen> 3 </since_tizen>
676         public void SetImage(string url)
677         {
678             if (null == url)
679             {
680                 throw new ArgumentNullException(nameof(url));
681             }
682
683             if (url.Contains(".json"))
684             {
685                 Tizen.Log.Fatal("NUI", "[ERROR] Please DO NOT set lottie file in ImageView! This is temporary checking, will be removed soon!");
686                 return;
687             }
688
689             Interop.ImageView.SetImage(SwigCPtr, url);
690             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
691
692             ResourceUrl = url;
693         }
694
695         /// <summary>
696         /// Queries if all resources required by a control are loaded and ready.<br />
697         /// Most resources are only loaded when the control is placed on the stage.<br />
698         /// True if the resources are loaded and ready, false otherwise.<br />
699         /// </summary>
700         /// <since_tizen> 3 </since_tizen>
701         public new bool IsResourceReady()
702         {
703             bool ret = Interop.View.IsResourceReady(SwigCPtr);
704             if (NDalicPINVOKE.SWIGPendingException.Pending)
705                 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
706             return ret;
707         }
708
709         /// <summary>
710         /// Forcefully reloads the image. All the visuals using this image will reload to the latest image.
711         /// </summary>
712         /// <since_tizen> 5 </since_tizen>
713         public void Reload()
714         {
715             PropertyValue attributes = new PropertyValue(0);
716             this.DoAction(ImageView.Property.IMAGE, Property.ActionReload, attributes);
717             attributes?.Dispose();
718         }
719
720         /// <summary>
721         /// Plays the animated GIF. This is also the default playback mode.
722         /// </summary>
723         /// <since_tizen> 5 </since_tizen>
724         public void Play()
725         {
726             PropertyValue attributes = new PropertyValue(0);
727             this.DoAction(ImageView.Property.IMAGE, Property.ActionPlay, attributes);
728             attributes?.Dispose();
729         }
730
731         /// <summary>
732         /// Pauses the animated GIF.
733         /// </summary>
734         /// <since_tizen> 5 </since_tizen>
735         public void Pause()
736         {
737             PropertyValue attributes = new PropertyValue(0);
738             this.DoAction(ImageView.Property.IMAGE, Property.ActionPause, attributes);
739             attributes?.Dispose();
740         }
741
742         /// <summary>
743         /// Stops the animated GIF.
744         /// </summary>
745         /// <since_tizen> 5 </since_tizen>
746         public void Stop()
747         {
748             PropertyValue attributes = new PropertyValue(0);
749             this.DoAction(ImageView.Property.IMAGE, Property.ActionStop, attributes);
750             attributes?.Dispose();
751         }
752
753         /// <summary>
754         /// Gets or sets the URL of the alpha mask.<br />
755         /// Optional.
756         /// </summary>
757         /// <since_tizen> 6</since_tizen>
758         [EditorBrowsable(EditorBrowsableState.Never)]
759         public string AlphaMaskURL
760         {
761             get
762             {
763                 string ret = "";
764                 PropertyMap imageMap = new PropertyMap();
765                 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
766                 image?.Get(imageMap);
767                 PropertyValue maskUrl = imageMap?.Find(ImageVisualProperty.AlphaMaskURL);
768                 maskUrl?.Get(out ret);
769                 _alphaMaskUrl = ret;
770
771                 imageMap?.Dispose();
772                 image?.Dispose();
773                 maskUrl?.Dispose();
774
775                 return ret;
776             }
777             set
778             {
779                 if (value == null)
780                 {
781                     value = "";
782                 }
783
784                 _alphaMaskUrl = value;
785
786                 PropertyValue setValue = new PropertyValue(value);
787                 UpdateImage(ImageVisualProperty.AlphaMaskURL, setValue);
788                 setValue?.Dispose();
789             }
790         }
791
792
793         /// <summary>
794         ///  Whether to crop image to mask or scale mask to fit image.
795         /// </summary>
796         /// <since_tizen> 6 </since_tizen>
797         public bool CropToMask
798         {
799             get
800             {
801                 bool ret = false;
802                 PropertyMap imageMap = new PropertyMap();
803                 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
804                 image?.Get(imageMap);
805                 PropertyValue cropUrl = imageMap?.Find(ImageVisualProperty.CropToMask);
806                 cropUrl?.Get(out ret);
807
808                 imageMap?.Dispose();
809                 image?.Dispose();
810                 cropUrl?.Dispose();
811
812                 return ret;
813             }
814             set
815             {
816                 PropertyValue setValue = new PropertyValue(value);
817                 UpdateImage(ImageVisualProperty.CropToMask, setValue);
818                 setValue.Dispose();
819             }
820         }
821
822         internal VisualFittingModeType CovertFittingModetoVisualFittingMode(FittingModeType value)
823         {
824             switch (value)
825             {
826                 case FittingModeType.ShrinkToFit:
827                     return VisualFittingModeType.FitKeepAspectRatio;
828                 case FittingModeType.ScaleToFill:
829                     return VisualFittingModeType.OverFitKeepAspectRatio;
830                 case FittingModeType.Center:
831                     return VisualFittingModeType.Center;
832                 case FittingModeType.Fill:
833                     return VisualFittingModeType.Fill;
834                 case FittingModeType.FitHeight:
835                     return VisualFittingModeType.FitHeight;
836                 case FittingModeType.FitWidth:
837                     return VisualFittingModeType.FitHeight;
838                 default:
839                     return VisualFittingModeType.Fill;
840             }
841         }
842
843         internal FittingModeType ConvertVisualFittingModetoFittingMode(VisualFittingModeType value)
844         {
845             switch (value)
846             {
847                 case VisualFittingModeType.FitKeepAspectRatio:
848                     return FittingModeType.ShrinkToFit;
849                 case VisualFittingModeType.OverFitKeepAspectRatio:
850                     return FittingModeType.ScaleToFill;
851                 case VisualFittingModeType.Center:
852                     return FittingModeType.Center;
853                 case VisualFittingModeType.Fill:
854                     return FittingModeType.Fill;
855                 case VisualFittingModeType.FitHeight:
856                     return FittingModeType.FitHeight;
857                 case VisualFittingModeType.FitWidth:
858                     return FittingModeType.FitWidth;
859                 default:
860                     return FittingModeType.ShrinkToFit;
861             }
862         }
863
864         /// <summary>
865         /// Gets or sets fitting options used when resizing images to fit.<br />
866         /// If not supplied, the default is FittingModeType.Fill.<br />
867         /// For normal quad images only.<br />
868         /// Optional.
869         /// </summary>
870         /// <since_tizen> 6 </since_tizen>
871         [EditorBrowsable(EditorBrowsableState.Never)]
872         public FittingModeType FittingMode
873         {
874             get
875             {
876                 int ret = (int)_fittingMode;
877                 PropertyMap imageMap = new PropertyMap();
878                 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
879                 image?.Get(imageMap);
880                 PropertyValue fittingMode = imageMap?.Find(Visual.Property.VisualFittingMode);
881                 fittingMode?.Get(out ret);
882                 _fittingMode = (VisualFittingModeType)ret;
883
884                 imageMap?.Dispose();
885                 image?.Dispose();
886                 fittingMode?.Dispose();
887
888                 return ConvertVisualFittingModetoFittingMode((VisualFittingModeType)ret);
889             }
890             set
891             {
892                 VisualFittingModeType ret = CovertFittingModetoVisualFittingMode(value);
893                 _fittingMode = ret;
894                 PropertyValue setValue = new PropertyValue((int)ret);
895                 UpdateImage(Visual.Property.VisualFittingMode, setValue);
896                 setValue?.Dispose();
897             }
898         }
899
900
901
902         /// <summary>
903         /// Gets or sets the desired image width.<br />
904         /// If not specified, the actual image width is used.<br />
905         /// For normal quad images only.<br />
906         /// Optional.
907         /// </summary>
908         /// <since_tizen> 6 </since_tizen>
909         [EditorBrowsable(EditorBrowsableState.Never)]
910         public int DesiredWidth
911         {
912             get
913             {
914                 PropertyMap imageMap = new PropertyMap();
915                 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
916                 image?.Get(imageMap);
917                 PropertyValue desireWidth = imageMap?.Find(ImageVisualProperty.DesiredWidth);
918                 desireWidth?.Get(out _desired_width);
919
920                 imageMap?.Dispose();
921                 image?.Dispose();
922                 desireWidth?.Dispose();
923
924                 return _desired_width;
925             }
926             set
927             {
928                 if (_desired_width != value)
929                 {
930                     _desired_width = value;
931                     UpdateImage(0, null);
932                 }
933             }
934         }
935
936         /// <summary>
937         /// Gets or sets the desired image height.<br />
938         /// If not specified, the actual image height is used.<br />
939         /// For normal quad images only.<br />
940         /// Optional.
941         /// </summary>
942         /// <since_tizen> 6 </since_tizen>
943         [EditorBrowsable(EditorBrowsableState.Never)]
944         public int DesiredHeight
945         {
946             get
947             {
948                 PropertyMap imageMap = new PropertyMap();
949                 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
950                 image?.Get(imageMap);
951                 PropertyValue desireheight = imageMap?.Find(ImageVisualProperty.DesiredHeight);
952                 desireheight?.Get(out _desired_height);
953
954                 imageMap?.Dispose();
955                 image?.Dispose();
956                 desireheight?.Dispose();
957
958                 return _desired_height;
959             }
960             set
961             {
962                 if (_desired_height != value)
963                 {
964                     _desired_height = value;
965                     UpdateImage(0, null);
966                 }
967             }
968         }
969
970         /// <summary>
971         /// Gets or sets ReleasePolicy for image.<br />
972         /// If not supplied, the default is ReleasePolicyType.Detached.<br />
973         /// </summary>
974         [EditorBrowsable(EditorBrowsableState.Never)]
975         public ReleasePolicyType ReleasePolicy
976         {
977             get
978             {
979                 int ret = (int)ReleasePolicyType.Detached;
980                 PropertyMap imageMap = new PropertyMap();
981                 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
982                 image?.Get(imageMap);
983                 PropertyValue releasePoli = imageMap?.Find(ImageVisualProperty.ReleasePolicy);
984                 releasePoli?.Get(out ret);
985
986                 imageMap?.Dispose();
987                 image?.Dispose();
988                 releasePoli?.Dispose();
989
990                 return (ReleasePolicyType)ret;
991             }
992             set
993             {
994                 PropertyValue setValue = new PropertyValue((int)value);
995                 UpdateImage(ImageVisualProperty.ReleasePolicy, setValue);
996                 setValue?.Dispose();
997             }
998         }
999
1000         /// <summary>
1001         /// Gets or sets the wrap mode for the u coordinate.<br />
1002         /// It decides how the texture should be sampled when the u coordinate exceeds the range of 0.0 to 1.0.<br />
1003         /// If not specified, the default is WrapModeType.Default(CLAMP).<br />
1004         /// For normal quad images only.<br />
1005         /// Optional.
1006         /// </summary>
1007         /// <since_tizen> 6 </since_tizen>
1008         [EditorBrowsable(EditorBrowsableState.Never)]
1009         public WrapModeType WrapModeU
1010         {
1011             get
1012             {
1013                 int ret = (int)WrapModeType.Default;
1014                 PropertyMap imageMap = new PropertyMap();
1015                 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
1016                 image?.Get(imageMap);
1017                 PropertyValue warpModeU = imageMap?.Find(ImageVisualProperty.WrapModeU);
1018                 warpModeU?.Get(out ret);
1019
1020                 imageMap?.Dispose();
1021                 image?.Dispose();
1022                 warpModeU?.Dispose();
1023
1024                 return (WrapModeType)ret;
1025             }
1026             set
1027             {
1028                 PropertyValue setValue = new PropertyValue((int)value);
1029                 UpdateImage(ImageVisualProperty.WrapModeU, setValue);
1030                 setValue?.Dispose();
1031             }
1032         }
1033
1034         /// <summary>
1035         /// Gets or sets the wrap mode for the v coordinate.<br />
1036         /// It decides how the texture should be sampled when the v coordinate exceeds the range of 0.0 to 1.0.<br />
1037         /// The first two elements indicate the top-left position of the area, and the last two elements are the areas of the width and the height respectively.<br />
1038         /// If not specified, the default is WrapModeType.Default(CLAMP).<br />
1039         /// For normal quad images only.
1040         /// Optional.
1041         /// </summary>
1042         /// <since_tizen> 6 </since_tizen>
1043         [EditorBrowsable(EditorBrowsableState.Never)]
1044         public WrapModeType WrapModeV
1045         {
1046             get
1047             {
1048                 int ret = (int)WrapModeType.Default;
1049                 PropertyMap imageMap = new PropertyMap();
1050                 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
1051                 image?.Get(imageMap);
1052                 PropertyValue wrapModeV = imageMap?.Find(ImageVisualProperty.WrapModeV);
1053                 wrapModeV?.Get(out ret);
1054
1055                 imageMap?.Dispose();
1056                 image?.Dispose();
1057                 wrapModeV?.Dispose();
1058
1059                 return (WrapModeType)ret;
1060             }
1061             set
1062             {
1063                 PropertyValue setValue = new PropertyValue((int)value);
1064                 UpdateImage(ImageVisualProperty.WrapModeV, setValue);
1065                 setValue?.Dispose();
1066             }
1067         }
1068
1069         internal Selector<string> ResourceUrlSelector
1070         {
1071             get => GetSelector<string>(resourceUrlSelector, ImageView.ResourceUrlProperty);
1072             set
1073             {
1074                 resourceUrlSelector?.Reset(this);
1075                 if (value == null) return;
1076
1077                 if (value.HasAll()) SetResourceUrl(value.All);
1078                 else resourceUrlSelector = new TriggerableSelector<string>(this, value, SetResourceUrl, true);
1079             }
1080         }
1081
1082         /// <summary>
1083         /// Get attributes, it is abstract function and must be override.
1084         /// </summary>
1085         [EditorBrowsable(EditorBrowsableState.Never)]
1086         protected override ViewStyle CreateViewStyle()
1087         {
1088             return new ImageViewStyle();
1089         }
1090
1091         internal void SetImage(string url, Uint16Pair size)
1092         {
1093             if (url.Contains(".json"))
1094             {
1095                 Tizen.Log.Fatal("NUI", "[ERROR] Please DO NOT set lottie file in ImageView! This is temporary checking, will be removed soon!");
1096                 return;
1097             }
1098
1099             Interop.ImageView.SetImage(SwigCPtr, url, Uint16Pair.getCPtr(size));
1100             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
1101
1102             ResourceUrl = url;
1103         }
1104
1105         internal ViewResourceReadySignal ResourceReadySignal(View view)
1106         {
1107             ViewResourceReadySignal ret = new ViewResourceReadySignal(Interop.View.ResourceReadySignal(View.getCPtr(view)), false);
1108             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
1109             return ret;
1110         }
1111
1112         internal override void ApplyCornerRadius()
1113         {
1114             base.ApplyCornerRadius();
1115
1116             UpdateImage(0, null);
1117         }
1118
1119         internal ResourceLoadingStatusType GetResourceStatus()
1120         {
1121             return (ResourceLoadingStatusType)Interop.View.GetVisualResourceStatus(this.SwigCPtr, Property.IMAGE);
1122         }
1123
1124         /// <summary>
1125         /// you can override it to clean-up your own resources.
1126         /// </summary>
1127         /// <param name="type">DisposeTypes</param>
1128         /// <since_tizen> 3 </since_tizen>
1129         protected override void Dispose(DisposeTypes type)
1130         {
1131             if (disposed)
1132             {
1133                 return;
1134             }
1135
1136             if (type == DisposeTypes.Explicit)
1137             {
1138                 //Called by User
1139                 //Release your own managed resources here.
1140                 //You should release all of your own disposable objects here.
1141                 _border?.Dispose();
1142                 _border = null;
1143                 borderSelector?.Reset(this);
1144                 resourceUrlSelector?.Reset(this);
1145             }
1146
1147             base.Dispose(type);
1148         }
1149
1150         /// This will not be public opened.
1151         [EditorBrowsable(EditorBrowsableState.Never)]
1152         protected override void ReleaseSwigCPtr(System.Runtime.InteropServices.HandleRef swigCPtr)
1153         {
1154             Interop.ImageView.DeleteImageView(swigCPtr);
1155         }
1156
1157         // Callback for View ResourceReady signal
1158         private void OnResourceReady(IntPtr data)
1159         {
1160             ResourceReadyEventArgs e = new ResourceReadyEventArgs();
1161             if (data != null)
1162             {
1163                 e.View = Registry.GetManagedBaseHandleFromNativePtr(data) as View;
1164             }
1165
1166             if (_resourceReadyEventHandler != null)
1167             {
1168                 _resourceReadyEventHandler(this, e);
1169             }
1170         }
1171
1172         private void SetResourceUrl(string value)
1173         {
1174             value = (value == null ? "" : value);
1175             if (value.StartsWith("*Resource*"))
1176             {
1177                 string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
1178                 value = value.Replace("*Resource*", resource);
1179             }
1180             _resourceUrl = value;
1181             UpdateImage(ImageVisualProperty.URL, new PropertyValue(value));
1182         }
1183
1184         private void SetBorder(Rectangle value)
1185         {
1186             if (value == null)
1187             {
1188                 return;
1189             }
1190             _border = new Rectangle(value);
1191             UpdateImage(NpatchImageVisualProperty.Border, new PropertyValue(_border));
1192         }
1193
1194         private void UpdateImageMap(PropertyMap fromMap)
1195         {
1196             PropertyMap imageMap = new PropertyMap();
1197
1198             PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
1199             image?.Get(imageMap);
1200             imageMap?.Merge(fromMap);
1201             PropertyValue setValue = new PropertyValue(imageMap);
1202             SetProperty(ImageView.Property.IMAGE, setValue);
1203
1204             imageMap?.Dispose();
1205             image?.Dispose();
1206             setValue?.Dispose();
1207         }
1208
1209         private void UpdateImage(int key, PropertyValue value)
1210         {
1211             PropertyMap imageMap = new PropertyMap();
1212
1213             if (_alphaMaskUrl != null)
1214             {
1215                 PropertyValue alphaMaskUrl = new PropertyValue(_alphaMaskUrl);
1216                 imageMap?.Insert(ImageVisualProperty.AlphaMaskURL, alphaMaskUrl);
1217                 alphaMaskUrl?.Dispose();
1218             }
1219
1220             if (string.IsNullOrEmpty(_resourceUrl))
1221             {
1222                 PropertyValue resourceUrl = new PropertyValue(_resourceUrl);
1223                 imageMap?.Insert(ImageVisualProperty.URL, resourceUrl);
1224                 PropertyValue setValue = new PropertyValue(imageMap);
1225                 SetProperty(ImageView.Property.IMAGE, setValue);
1226                 resourceUrl?.Dispose();
1227                 setValue?.Dispose();
1228                 return;
1229             }
1230
1231             if (_border == null)
1232             {
1233                 PropertyValue image = new PropertyValue((int)Visual.Type.Image);
1234                 imageMap?.Insert(Visual.Property.Type, image);
1235                 image?.Dispose();
1236             }
1237             else
1238             {
1239                 PropertyValue nPatch = new PropertyValue((int)Visual.Type.NPatch);
1240                 imageMap?.Insert(Visual.Property.Type, nPatch);
1241                 nPatch?.Dispose();
1242                 PropertyValue border = new PropertyValue(_border);
1243                 imageMap?.Insert(NpatchImageVisualProperty.Border, border);
1244                 border?.Dispose();
1245             }
1246
1247             if(key != Visual.Property.VisualFittingMode && _fittingMode != VisualFittingModeType.Fill)
1248             {
1249                 PropertyValue fittingMode = new PropertyValue((int)_fittingMode);
1250                 imageMap?.Insert(Visual.Property.VisualFittingMode, fittingMode);
1251                 fittingMode?.Dispose();
1252             }
1253
1254             PropertyValue synchronosLoading = new PropertyValue(_synchronosLoading);
1255             imageMap?.Insert(NpatchImageVisualProperty.SynchronousLoading, synchronosLoading);
1256             synchronosLoading?.Dispose();
1257
1258             if (backgroundExtraData != null && backgroundExtraData.CornerRadius != null)
1259             {
1260                 // TODO Fix to support Vector4 for corner radius after dali support it.
1261                 //      Current code only gets first argument of Vector4.
1262                 using (var cornerRadius = new PropertyValue(backgroundExtraData.CornerRadius.X))
1263                 using (var cornerRadiusPolicy = new PropertyValue((int)backgroundExtraData.CornerRadiusPolicy))
1264                 {
1265                     imageMap.Insert(Visual.Property.CornerRadius, cornerRadius);
1266                     imageMap.Insert(Visual.Property.CornerRadiusPolicy, new PropertyValue((int)(backgroundExtraData.CornerRadiusPolicy)));
1267                 }
1268             }
1269
1270             if (value != null)
1271             {
1272                 imageMap?.Insert(key, value);
1273             }
1274
1275             // Do Fitting Buffer when desired dimension is set
1276             if (_desired_width != -1 && _desired_height != -1)
1277             {
1278                 if (_resourceUrl != null)
1279                 {
1280                     Size2D imageSize = ImageLoading.GetOriginalImageSize(_resourceUrl, true);
1281
1282                     int adjustedDesiredWidth, adjustedDesiredHeight;
1283                     float aspectOfDesiredSize = (float)_desired_height / (float)_desired_width;
1284                     float aspectOfImageSize = (float)imageSize.Height / (float)imageSize.Width;
1285                     if (aspectOfImageSize > aspectOfDesiredSize)
1286                     {
1287                         adjustedDesiredWidth = _desired_width;
1288                         adjustedDesiredHeight = imageSize.Height * _desired_width / imageSize.Width;
1289                     }
1290                     else
1291                     {
1292                         adjustedDesiredWidth = imageSize.Width * _desired_height / imageSize.Height;
1293                         adjustedDesiredHeight = _desired_height;
1294                     }
1295
1296                     PropertyValue returnWidth = new PropertyValue(adjustedDesiredWidth);
1297                     imageMap?.Insert(ImageVisualProperty.DesiredWidth, returnWidth);
1298                     returnWidth?.Dispose();
1299                     PropertyValue returnHeight = new PropertyValue(adjustedDesiredHeight);
1300                     imageMap?.Insert(ImageVisualProperty.DesiredHeight, returnHeight);
1301                     returnHeight?.Dispose();
1302                     PropertyValue scaleToFit = new PropertyValue((int)FittingModeType.ScaleToFill);
1303                     imageMap?.Insert(ImageVisualProperty.FittingMode, scaleToFit);
1304                     scaleToFit?.Dispose();
1305                 }
1306             }
1307
1308             UpdateImageMap(imageMap);
1309
1310             imageMap?.Dispose();
1311             imageMap = null;
1312         }
1313
1314
1315         private void OnResourceLoaded(IntPtr view)
1316         {
1317             ResourceLoadedEventArgs e = new ResourceLoadedEventArgs();
1318             e.Status = (ResourceLoadingStatusType)Interop.View.GetVisualResourceStatus(this.SwigCPtr, Property.IMAGE);
1319
1320             if (_resourceLoadedEventHandler != null)
1321             {
1322                 _resourceLoadedEventHandler(this, e);
1323             }
1324         }
1325
1326         /// <summary>
1327         /// Event arguments of resource ready.
1328         /// </summary>
1329         /// <since_tizen> 3 </since_tizen>
1330         public class ResourceReadyEventArgs : EventArgs
1331         {
1332             private View _view;
1333
1334             /// <summary>
1335             /// The view whose resource is ready.
1336             /// </summary>
1337             /// <since_tizen> 3 </since_tizen>
1338             public View View
1339             {
1340                 get
1341                 {
1342                     return _view;
1343                 }
1344                 set
1345                 {
1346                     _view = value;
1347                 }
1348             }
1349         }
1350
1351         internal class ResourceLoadedEventArgs : EventArgs
1352         {
1353             private ResourceLoadingStatusType status = ResourceLoadingStatusType.Invalid;
1354             public ResourceLoadingStatusType Status
1355             {
1356                 get
1357                 {
1358                     return status;
1359                 }
1360                 set
1361                 {
1362                     status = value;
1363                 }
1364             }
1365         }
1366
1367         internal new class Property
1368         {
1369             internal static readonly int IMAGE = Interop.ImageView.ImageGet();
1370             internal static readonly int PreMultipliedAlpha = Interop.ImageView.PreMultipliedAlphaGet();
1371             internal static readonly int PixelArea = Interop.ImageView.PixelAreaGet();
1372             internal static readonly int ActionReload = Interop.ImageView.ImageVisualActionReloadGet();
1373             internal static readonly int ActionPlay = Interop.ImageView.ImageVisualActionPlayGet();
1374             internal static readonly int ActionPause = Interop.ImageView.ImageVisualActionPauseGet();
1375             internal static readonly int ActionStop = Interop.ImageView.ImageVisualActionStopGet();
1376         }
1377
1378         private enum ImageType
1379         {
1380             /// <summary>
1381             /// For Normal Image.
1382             /// </summary>
1383             Normal = 0,
1384
1385             /// <summary>
1386             /// For normal image, with synchronous loading and orientation correction property
1387             /// </summary>
1388             Specific = 1,
1389
1390             /// <summary>
1391             /// For nine-patch image
1392             /// </summary>
1393             Npatch = 2,
1394         }
1395
1396         private void OnBorderChanged(int x, int y, int width, int height)
1397         {
1398             Border = new Rectangle(x, y, width, height);
1399         }
1400         private void OnPixelAreaChanged(float x, float y, float z, float w)
1401         {
1402             PixelArea = new RelativeVector4(x, y, z, w);
1403         }
1404     }
1405 }