[NUI] Make Action id as internal static readonly
[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.Collections.Generic;
19 using System.Runtime.InteropServices;
20 using System.ComponentModel;
21 using Tizen.NUI.Binding;
22
23 namespace Tizen.NUI.BaseComponents
24 {
25
26     /// <summary>
27     /// ImageView is a class for displaying an image resource.<br />
28     /// An instance of ImageView can be created using a URL or an image instance.<br />
29     /// </summary>
30     /// <since_tizen> 3 </since_tizen>
31     public partial class ImageView : View
32     {
33         static ImageView() { }
34
35         private EventHandler<ResourceReadyEventArgs> _resourceReadyEventHandler;
36         private ResourceReadyEventCallbackType _resourceReadyEventCallback;
37         private EventHandler<ResourceLoadedEventArgs> _resourceLoadedEventHandler;
38         private _resourceLoadedCallbackType _resourceLoadedCallback;
39
40         /// <summary>
41         /// Convert non-null string that some keyword change as application specific directory.
42         /// </summary>
43         /// <param name="value">Inputed and replaced after this function finished</param>
44         /// <returns>Replaced url</returns>
45         private static string ConvertResourceUrl(ref string value)
46         {
47             value ??= "";
48             if (value.StartsWith("*Resource*"))
49             {
50                 string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
51                 value = value.Replace("*Resource*", resource);
52             }
53             return value;
54         }
55
56         // Collection of image-sensitive properties.
57         private static readonly List<int> cachedImagePropertyKeyList = new List<int> {
58             Visual.Property.Type,
59             ImageVisualProperty.URL,
60             ImageVisualProperty.AlphaMaskURL,
61             ImageVisualProperty.CropToMask,
62             Visual.Property.VisualFittingMode,
63             ImageVisualProperty.DesiredWidth,
64             ImageVisualProperty.DesiredHeight,
65             ImageVisualProperty.ReleasePolicy,
66             ImageVisualProperty.WrapModeU,
67             ImageVisualProperty.WrapModeV,
68             ImageVisualProperty.SynchronousLoading,
69             Visual.Property.PremultipliedAlpha,
70             ImageVisualProperty.OrientationCorrection,
71             ImageVisualProperty.FastTrackUploading,
72             NpatchImageVisualProperty.Border,
73             NpatchImageVisualProperty.BorderOnly,
74         };
75         internal PropertyMap cachedImagePropertyMap;
76         internal bool imagePropertyUpdatedFlag = false;
77
78         private bool imagePropertyUpdateProcessAttachedFlag = false;
79         private Rectangle _border;
80         private string _resourceUrl = "";
81         private int _desired_width = -1;
82         private int _desired_height = -1;
83         private bool _fastTrackUploading = false;
84         private TriggerableSelector<string> resourceUrlSelector;
85         private TriggerableSelector<Rectangle> borderSelector;
86
87         private RelativeVector4 internalPixelArea;
88
89         /// <summary>
90         /// Creates an initialized ImageView.
91         /// </summary>
92         /// <since_tizen> 3 </since_tizen>
93         public ImageView() : this(Interop.ImageView.New(), true)
94         {
95             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
96         }
97
98         /// This will be public opened in next release of tizen after ACR done. Before ACR, it is used as HiddenAPI (InhouseAPI).
99         [EditorBrowsable(EditorBrowsableState.Never)]
100         public ImageView(ViewStyle viewStyle) : this(Interop.ImageView.New(), true, viewStyle)
101         {
102         }
103
104         /// <summary>
105         /// Creates an initialized ImageView with setting the status of shown or hidden.
106         /// </summary>
107         /// <param name="shown">false : Not displayed (hidden), true : displayed (shown)</param>
108         /// This will be public opened in next release of tizen after ACR done. Before ACR, it is used as HiddenAPI (InhouseAPI).
109         [EditorBrowsable(EditorBrowsableState.Never)]
110         public ImageView(bool shown) : this(Interop.ImageView.New(), true)
111         {
112             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
113             SetVisible(shown);
114         }
115
116         /// <summary>
117         /// Creates an initialized ImageView from a URL to an image resource.<br />
118         /// If the string is empty, ImageView will not display anything.<br />
119         /// </summary>
120         /// <param name="url">The URL of the image resource to display.</param>
121         /// <since_tizen> 3 </since_tizen>
122         public ImageView(string url) : this(Interop.ImageView.New(ConvertResourceUrl(ref url)), true)
123         {
124             _resourceUrl = url;
125
126             // Update cached property. Note that we should not re-create new visual.
127             using (PropertyValue urlValue = new PropertyValue(_resourceUrl))
128             {
129                 UpdateImage(ImageVisualProperty.URL, urlValue, false);
130             }
131             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
132
133         }
134
135         /// <summary>
136         /// Creates an initialized ImageView from a URL to an image resource with setting shown or hidden.
137         /// </summary>
138         /// <param name="url">The URL of the image resource to display.</param>
139         /// <param name="shown">false : Not displayed (hidden), true : displayed (shown)</param>
140         /// This will be public opened in next release of tizen after ACR done. Before ACR, it is used as HiddenAPI (InhouseAPI).
141         [EditorBrowsable(EditorBrowsableState.Never)]
142         public ImageView(string url, bool shown) : this(Interop.ImageView.New(ConvertResourceUrl(ref url)), true)
143         {
144             _resourceUrl = url;
145
146             // Update cached property. Note that we should not re-create new visual.
147             using (PropertyValue urlValue = new PropertyValue(_resourceUrl))
148             {
149                 UpdateImage(ImageVisualProperty.URL, urlValue, false);
150             }
151             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
152             SetVisible(shown);
153         }
154
155         internal ImageView(string url, Uint16Pair size, bool shown = true) : this(Interop.ImageView.New(ConvertResourceUrl(ref url), Uint16Pair.getCPtr(size)), true)
156         {
157             _resourceUrl = url;
158             _desired_width = size?.GetWidth() ?? -1;
159             _desired_height = size?.GetHeight() ?? -1;
160
161             // Update cached property. Note that we should not re-create new visual.
162             using (PropertyValue urlValue = new PropertyValue(_resourceUrl))
163             {
164                 UpdateImage(ImageVisualProperty.URL, urlValue, false);
165             }
166             using (PropertyValue desiredWidthValue = new PropertyValue(_desired_width))
167             {
168                 UpdateImage(ImageVisualProperty.DesiredWidth, desiredWidthValue, false);
169             }
170             using (PropertyValue desiredHeightValue = new PropertyValue(_desired_height))
171             {
172                 UpdateImage(ImageVisualProperty.DesiredWidth, desiredHeightValue, false);
173             }
174             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
175
176             if (!shown)
177             {
178                 SetVisible(false);
179             }
180         }
181
182         internal ImageView(global::System.IntPtr cPtr, bool cMemoryOwn, ViewStyle viewStyle, bool shown = true) : base(cPtr, cMemoryOwn, viewStyle)
183         {
184             if (!shown)
185             {
186                 SetVisible(false);
187             }
188         }
189
190         internal ImageView(global::System.IntPtr cPtr, bool cMemoryOwn, bool shown = true) : base(cPtr, cMemoryOwn, null)
191         {
192             if (!shown)
193             {
194                 SetVisible(false);
195             }
196         }
197
198         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
199         private delegate void ResourceReadyEventCallbackType(IntPtr data);
200         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
201         private delegate void _resourceLoadedCallbackType(IntPtr view);
202
203         /// <summary>
204         /// An event for ResourceReady signal which can be used to subscribe or unsubscribe the event handler.<br />
205         /// This signal is emitted after all resources required by a control are loaded and ready.<br />
206         /// Most resources are only loaded when the control is placed on the stage.<br />
207         /// </summary>
208         /// <since_tizen> 3 </since_tizen>
209         public event EventHandler<ResourceReadyEventArgs> ResourceReady
210         {
211             add
212             {
213                 if (_resourceReadyEventHandler == null)
214                 {
215                     _resourceReadyEventCallback = OnResourceReady;
216                     ViewResourceReadySignal resourceReadySignal = ResourceReadySignal(this);
217                     resourceReadySignal?.Connect(_resourceReadyEventCallback);
218                     resourceReadySignal?.Dispose();
219                 }
220
221                 _resourceReadyEventHandler += value;
222             }
223
224             remove
225             {
226                 _resourceReadyEventHandler -= value;
227
228                 ViewResourceReadySignal resourceReadySignal = ResourceReadySignal(this);
229                 if (_resourceReadyEventHandler == null && resourceReadySignal?.Empty() == false)
230                 {
231                     resourceReadySignal?.Disconnect(_resourceReadyEventCallback);
232                 }
233                 resourceReadySignal?.Dispose();
234             }
235         }
236
237         internal event EventHandler<ResourceLoadedEventArgs> ResourceLoaded
238         {
239             add
240             {
241                 if (_resourceLoadedEventHandler == null)
242                 {
243                     _resourceLoadedCallback = OnResourceLoaded;
244                     ViewResourceReadySignal resourceReadySignal = this.ResourceReadySignal(this);
245                     resourceReadySignal?.Connect(_resourceLoadedCallback);
246                     resourceReadySignal?.Dispose();
247                 }
248
249                 _resourceLoadedEventHandler += value;
250             }
251             remove
252             {
253                 _resourceLoadedEventHandler -= value;
254                 ViewResourceReadySignal resourceReadySignal = this.ResourceReadySignal(this);
255                 if (_resourceLoadedEventHandler == null && resourceReadySignal?.Empty() == false)
256                 {
257                     resourceReadySignal?.Disconnect(_resourceLoadedCallback);
258                 }
259                 resourceReadySignal?.Dispose();
260             }
261         }
262
263         /// <summary>
264         /// Enumeration for LoadingStatus of image.
265         /// </summary>
266         /// <since_tizen> 5 </since_tizen>
267         public enum LoadingStatusType
268         {
269             /// <summary>
270             /// Loading preparing status.
271             /// </summary>
272             /// <since_tizen> 5 </since_tizen>
273             Preparing,
274             /// <summary>
275             /// Loading ready status.
276             /// </summary>
277             /// <since_tizen> 5 </since_tizen>
278             Ready,
279             /// <summary>
280             /// Loading failed status.
281             /// </summary>
282             /// <since_tizen> 5 </since_tizen>
283             Failed
284         }
285
286         /// <summary>
287         /// Enumeration for MaskingMode of image.
288         /// </summary>
289         [EditorBrowsable(EditorBrowsableState.Never)]
290         public enum MaskingModeType
291         {
292             /// <summary>
293             /// Applies alpha masking on rendering time.
294             /// </summary>
295             [EditorBrowsable(EditorBrowsableState.Never)]
296             MaskingOnRendering,
297             /// <summary>
298             /// Applies alpha masking on loading time.
299             /// </summary>
300             [EditorBrowsable(EditorBrowsableState.Never)]
301             MaskingOnLoading
302         }
303
304         /// <summary>
305         /// ImageView ResourceUrl, type string.
306         /// This is one of mandatory property. Even if not set or null set, it sets empty string ("") internally.
307         /// When it is set as null, it gives empty string ("") to be read.
308         /// </summary>
309         /// <since_tizen> 3 </since_tizen>
310         public string ResourceUrl
311         {
312             get
313             {
314                 return (string)GetValue(ResourceUrlProperty);
315             }
316             set
317             {
318                 SetValue(ResourceUrlProperty, value);
319                 NotifyPropertyChanged();
320             }
321         }
322
323         /// <summary>
324         /// This will be deprecated, Use Image instead. <br />
325         /// ImageView ImageMap, type PropertyMap: string if it is a URL, map otherwise.
326         /// </summary>
327         /// <since_tizen> 3 </since_tizen>
328         [Obsolete("Do not use this, that will be deprecated. Use Image property instead.")]
329         [EditorBrowsable(EditorBrowsableState.Never)]
330         public PropertyMap ImageMap
331         {
332             get
333             {
334                 return GetValue(ImageMapProperty) as PropertyMap;
335             }
336             set
337             {
338                 SetValue(ImageMapProperty, value);
339                 NotifyPropertyChanged();
340             }
341         }
342         private PropertyMap InternalImageMap
343         {
344             get
345             {
346                 if (_border == null)
347                 {
348                     // Sync as current properties
349                     UpdateImage();
350
351                     // Get current properties force.
352                     PropertyMap returnValue = new PropertyMap();
353                     PropertyValue image = GetProperty(ImageView.Property.IMAGE);
354                     image?.Get(returnValue);
355                     image?.Dispose();
356
357                     // Update cached property map
358                     if (returnValue != null)
359                     {
360                         MergeCachedImageVisualProperty(returnValue);
361                     }
362                     return returnValue;
363                 }
364                 else
365                 {
366                     return null;
367                 }
368             }
369             set
370             {
371                 if (_border == null)
372                 {
373                     PropertyValue setValue = new Tizen.NUI.PropertyValue(value);
374                     SetProperty(ImageView.Property.IMAGE, setValue);
375
376                     // Image properties are changed hardly. We should ignore lazy UpdateImage
377                     imagePropertyUpdatedFlag = false;
378                     cachedImagePropertyMap?.Dispose();
379                     cachedImagePropertyMap = null;
380                     MergeCachedImageVisualProperty(value);
381
382                     NotifyPropertyChanged();
383                     setValue?.Dispose();
384                 }
385             }
386         }
387
388         /// <summary>
389         /// ImageView Image, type PropertyMap: string if it is a URL, map otherwise.
390         /// </summary>
391         /// <remarks>
392         /// This PropertyMap use a <see cref="ImageVisualProperty"/>. <br />
393         /// See <see cref="ImageVisualProperty"/> for a detailed description. <br />
394         /// you can also use <see cref="Visual.Property"/>. <br />
395         /// See <see cref="Visual.Property"/> for a detailed description. <br />
396         /// </remarks>
397         /// <example>
398         /// The following example demonstrates how to use the Image property.
399         /// <code>
400         /// PropertyMap map = new PropertyMap();
401         /// map.Insert(Visual.Property.Type, new PropertyValue((int)Visual.Type.Image));
402         /// map.Insert(ImageVisualProperty.AlphaMaskURL, new PropertyValue(url));
403         /// map.Insert(ImageVisualProperty.FittingMode, new PropertyValue((int)FittingModeType.ScaleToFill);
404         /// imageview.Image = map;
405         /// </code>
406         /// </example>
407         /// <since_tizen> 4 </since_tizen>
408         public PropertyMap Image
409         {
410             get
411             {
412                 if (_border == null)
413                 {
414                     return (PropertyMap)GetValue(ImageProperty);
415                 }
416                 else
417                 {
418                     return null;
419                 }
420             }
421             set
422             {
423                 if (_border == null)
424                 {
425                     SetValue(ImageProperty, value);
426                     NotifyPropertyChanged();
427                 }
428             }
429         }
430
431         /// <summary>
432         /// ImageView PreMultipliedAlpha, type Boolean.<br />
433         /// Image must be initialized.<br />
434         /// </summary>
435         /// <since_tizen> 3 </since_tizen>
436         public bool PreMultipliedAlpha
437         {
438             get
439             {
440                 return (bool)GetValue(PreMultipliedAlphaProperty);
441             }
442             set
443             {
444                 SetValue(PreMultipliedAlphaProperty, value);
445                 NotifyPropertyChanged();
446             }
447         }
448
449         /// <summary>
450         /// ImageView PixelArea, type Vector4 (Animatable property).<br />
451         /// Pixel area is a relative value with the whole image area as [0.0, 0.0, 1.0, 1.0].<br />
452         /// </summary>
453         /// <remarks>
454         /// The property cascade chaining set is possible. For example, this (imageView.PixelArea.X = 0.1f;) is possible.
455         /// </remarks>
456         /// <since_tizen> 3 </since_tizen>
457         public RelativeVector4 PixelArea
458         {
459             get
460             {
461                 return (RelativeVector4)GetValue(PixelAreaProperty);
462             }
463             set
464             {
465                 SetValue(PixelAreaProperty, value);
466                 NotifyPropertyChanged();
467             }
468         }
469
470         /// <summary>
471         /// The border of the image in the order: left, right, bottom, top.<br />
472         /// If set, ImageMap will be ignored.<br />
473         /// For N-Patch images only.<br />
474         /// Optional.
475         /// </summary>
476         /// <remarks>
477         /// The property cascade chaining set is possible. For example, this (imageView.Border.X = 1;) is possible.
478         /// </remarks>
479         /// <since_tizen> 3 </since_tizen>
480         public Rectangle Border
481         {
482             get
483             {
484                 Rectangle temp = (Rectangle)GetValue(BorderProperty);
485                 if (null == temp)
486                 {
487                     return null;
488                 }
489                 else
490                 {
491                     return new Rectangle(OnBorderChanged, temp.X, temp.Y, temp.Width, temp.Height);
492                 }
493             }
494             set
495             {
496                 SetValue(BorderProperty, value);
497                 NotifyPropertyChanged();
498             }
499         }
500
501         /// <summary>
502         /// Gets or sets whether to draw the borders only (if true).<br />
503         /// If not specified, the default is false.<br />
504         /// For N-Patch images only.<br />
505         /// Optional.
506         /// </summary>
507         /// <since_tizen> 3 </since_tizen>
508         public bool BorderOnly
509         {
510             get
511             {
512                 return (bool)GetValue(BorderOnlyProperty);
513             }
514             set
515             {
516                 SetValue(BorderOnlyProperty, value);
517                 NotifyPropertyChanged();
518             }
519         }
520
521         /// <summary>
522         /// Gets or sets whether to synchronous loading the resourceurl of image.<br />
523         /// </summary>
524         /// <since_tizen> 3 </since_tizen>
525         [Obsolete("This has been deprecated since API9 and will be removed in API11. Use SynchronousLoading instead.")]
526         public bool SynchronosLoading
527         {
528             get
529             {
530                 return SynchronousLoading;
531             }
532             set
533             {
534                 SynchronousLoading = value;
535             }
536         }
537
538         /// <summary>
539         /// Gets or sets whether the image of the ResourceUrl property will be loaded synchronously.<br />
540         /// </summary>
541         /// <remarks>
542         /// Changing this property make this ImageView load image synchronously at the next loading
543         /// by following operation: <see cref="Reload"/>, <see cref="SetImage(string)"/>,
544         /// and by some properties those cause reloading: <see cref="ResourceUrl"/>, <see cref="PreMultipliedAlpha"/> and etc.
545         /// </remarks>
546         /// <since_tizen> 9 </since_tizen>
547         public bool SynchronousLoading
548         {
549             get
550             {
551                 return (bool)GetValue(SynchronousLoadingProperty);
552             }
553             set
554             {
555                 SetValue(SynchronousLoadingProperty, value);
556                 NotifyPropertyChanged();
557             }
558         }
559
560         /// <summary>
561         /// Gets or sets whether to automatically correct the orientation of an image.<br />
562         /// </summary>
563         /// <since_tizen> 5 </since_tizen>
564         public bool OrientationCorrection
565         {
566             get
567             {
568                 return (bool)GetValue(OrientationCorrectionProperty);
569             }
570             set
571             {
572                 SetValue(OrientationCorrectionProperty, value);
573                 NotifyPropertyChanged();
574             }
575         }
576
577         /// <summary>
578         /// Gets or sets whether to apply mask on GPU or not.<br />
579         /// </summary>
580         [EditorBrowsable(EditorBrowsableState.Never)]
581         public MaskingModeType MaskingMode
582         {
583             get
584             {
585                 return (MaskingModeType)GetValue(MaskingModeProperty);
586             }
587             set
588             {
589                 SetValue(MaskingModeProperty, value);
590                 NotifyPropertyChanged();
591             }
592         }
593
594         private MaskingModeType InternalMaskingMode
595         {
596             get
597             {
598                 int ret = (int)MaskingModeType.MaskingOnLoading;
599
600                 PropertyValue maskingMode = GetCachedImageVisualProperty(ImageVisualProperty.MaskingMode);
601                 maskingMode?.Get(out ret);
602                 maskingMode?.Dispose();
603
604                 return (MaskingModeType)ret;
605             }
606             set
607             {
608                 MaskingModeType ret = value;
609                 PropertyValue setValue = new PropertyValue((int)ret);
610                 UpdateImage(ImageVisualProperty.MaskingMode, setValue);
611                 setValue?.Dispose();
612             }
613         }
614
615         /// <summary>
616         /// Gets or sets whether to apply fast track uploading or not.<br />
617         /// </summary>
618         /// <remarks>
619         /// If we use fast track uploading feature, It can upload texture without event-thead dependency. But also,<br />
620         ///  - Texture size is invalid until ResourceReady signal comes.<br />
621         ///  - Texture cannot be cached (We always try to load new image).<br />
622         ///  - Seamless visual change didn't supported.<br />
623         ///  - Alpha masking didn't supported. If you try, It will load as normal case.<br />
624         ///  - Synchronous loading didn't supported. If you try, It will load as normal case.<br />
625         ///  - Reload action didn't supported. If you try, It will load as normal case.<br />
626         ///  - Atlas loading didn't supported. If you try, It will load as normal case.<br />
627         ///  - Custom shader didn't supported. If you try, It will load as normal case.
628         /// </remarks>
629         [EditorBrowsable(EditorBrowsableState.Never)]
630         public bool FastTrackUploading
631         {
632             get
633             {
634                 return (bool)GetValue(FastTrackUploadingProperty);
635             }
636             set
637             {
638                 SetValue(FastTrackUploadingProperty, value);
639                 NotifyPropertyChanged();
640             }
641         }
642
643         private bool InternalFastTrackUploading
644         {
645             get
646             {
647                 PropertyValue fastTrackUploading = GetCachedImageVisualProperty(ImageVisualProperty.FastTrackUploading);
648                 fastTrackUploading?.Get(out _fastTrackUploading);
649                 fastTrackUploading?.Dispose();
650
651                 return _fastTrackUploading;
652             }
653             set
654             {
655                 if (_fastTrackUploading != value)
656                 {
657                     _fastTrackUploading = value;
658
659                     PropertyValue setValue = new PropertyValue(_fastTrackUploading);
660                     UpdateImage(ImageVisualProperty.FastTrackUploading, setValue);
661                     setValue?.Dispose();
662
663                     if (_fastTrackUploading && !string.IsNullOrEmpty(_resourceUrl))
664                     {
665                         // Special case. If user set FastTrackUploading mean, user want to upload image As-Soon-As-Possible.
666                         // Create ImageVisual synchronously.
667                         UpdateImage();
668                     }
669                 }
670             }
671         }
672
673         /// <summary>
674         /// Gets the loading state of the visual resource.
675         /// </summary>
676         /// <since_tizen> 5 </since_tizen>
677         public ImageView.LoadingStatusType LoadingStatus
678         {
679             get
680             {
681                 return (ImageView.LoadingStatusType)Interop.View.GetVisualResourceStatus(SwigCPtr, (int)Property.IMAGE);
682             }
683         }
684
685         /// <summary>
686         /// Downcasts a handle to imageView handle.
687         /// </summary>
688         /// <exception cref="ArgumentNullException"> Thrown when handle is null. </exception>
689         /// Do not use this, that will be deprecated. Use as keyword instead.
690         /// <since_tizen> 3 </since_tizen>
691         [Obsolete("Do not use this, that will be deprecated. Use as keyword instead. " +
692         "Like: " +
693         "BaseHandle handle = new ImageView(imagePath); " +
694         "ImageView image = handle as ImageView")]
695         [EditorBrowsable(EditorBrowsableState.Never)]
696         public static ImageView DownCast(BaseHandle handle)
697         {
698             if (null == handle)
699             {
700                 throw new ArgumentNullException(nameof(handle));
701             }
702             ImageView ret = Registry.GetManagedBaseHandleFromNativePtr(handle) as ImageView;
703             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
704             return ret;
705         }
706
707         /// <summary>
708         /// Sets this ImageView from the given URL.<br />
709         /// If the URL is empty, ImageView will not display anything.<br />
710         /// </summary>
711         /// <param name="url">The URL to the image resource to display.</param>
712         /// <exception cref="ArgumentNullException"> Thrown when url is null. </exception>
713         /// <since_tizen> 3 </since_tizen>
714         public void SetImage(string url)
715         {
716             if (null == url)
717             {
718                 throw new ArgumentNullException(nameof(url));
719             }
720
721             if (url.Contains(".json"))
722             {
723                 Tizen.Log.Fatal("NUI", "[ERROR] Do not set lottie file in ImageView! This is temporary checking, will be removed soon!");
724                 return;
725             }
726
727             Interop.ImageView.SetImage(SwigCPtr, ConvertResourceUrl(ref url));
728             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
729
730             _resourceUrl = url;
731             // Update cached property. Note that we should not re-create new visual.
732             using (PropertyValue urlValue = new PropertyValue(_resourceUrl))
733             {
734                 UpdateImage(ImageVisualProperty.URL, urlValue, false);
735             }
736             imagePropertyUpdatedFlag = false;
737         }
738
739         /// <summary>
740         /// Queries if all resources required by a control are loaded and ready.<br />
741         /// Most resources are only loaded when the control is placed on the stage.<br />
742         /// True if the resources are loaded and ready, false otherwise.<br />
743         /// </summary>
744         /// <since_tizen> 3 </since_tizen>
745         public new bool IsResourceReady()
746         {
747             bool ret = Interop.View.IsResourceReady(SwigCPtr);
748             if (NDalicPINVOKE.SWIGPendingException.Pending)
749                 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
750             return ret;
751         }
752
753         /// <summary>
754         /// Forcefully reloads the image. All the visuals using this image will reload to the latest image.
755         /// </summary>
756         /// <since_tizen> 5 </since_tizen>
757         public void Reload()
758         {
759             // Sync as current properties
760             UpdateImage();
761
762
763             Interop.View.DoActionWithEmptyAttributes(this.SwigCPtr, ImageView.Property.IMAGE, ActionReload);
764         }
765
766         /// <summary>
767         /// Plays the animated GIF. This is also the default playback mode.
768         /// </summary>
769         /// <since_tizen> 5 </since_tizen>
770         public void Play()
771         {
772             // Sync as current properties
773             UpdateImage();
774
775
776             Interop.View.DoActionWithEmptyAttributes(this.SwigCPtr, ImageView.Property.IMAGE, ActionPlay);
777         }
778
779         /// <summary>
780         /// Pauses the animated GIF.
781         /// </summary>
782         /// <since_tizen> 5 </since_tizen>
783         public void Pause()
784         {
785             // Sync as current properties
786             UpdateImage();
787
788
789             Interop.View.DoActionWithEmptyAttributes(this.SwigCPtr, ImageView.Property.IMAGE, ActionPause);
790         }
791
792         /// <summary>
793         /// Stops the animated GIF.
794         /// </summary>
795         /// <since_tizen> 5 </since_tizen>
796         public void Stop()
797         {
798             // Sync as current properties
799             UpdateImage();
800
801
802
803             Interop.View.DoActionWithEmptyAttributes(this.SwigCPtr, ImageView.Property.IMAGE, ActionStop);
804         }
805
806         /// <summary>
807         /// Gets or sets the URL of the alpha mask.<br />
808         /// Optional.
809         /// </summary>
810         /// <since_tizen> 6</since_tizen>
811         [EditorBrowsable(EditorBrowsableState.Never)]
812         public string AlphaMaskURL
813         {
814             get
815             {
816                 return GetValue(AlphaMaskURLProperty) as string;
817             }
818             set
819             {
820                 SetValue(AlphaMaskURLProperty, value);
821                 NotifyPropertyChanged();
822             }
823         }
824
825         private string InternalAlphaMaskURL
826         {
827             get
828             {
829                 string ret = "";
830
831                 PropertyValue maskUrl = GetCachedImageVisualProperty(ImageVisualProperty.AlphaMaskURL);
832                 maskUrl?.Get(out ret);
833                 maskUrl?.Dispose();
834
835                 return ret;
836             }
837             set
838             {
839                 PropertyValue setValue = new PropertyValue(value ?? "");
840                 UpdateImage(ImageVisualProperty.AlphaMaskURL, setValue);
841                 // When we never set CropToMask property before, we should set default value as true.
842                 using (PropertyValue cropToMask = GetCachedImageVisualProperty(ImageVisualProperty.CropToMask))
843                 {
844                     if (cropToMask == null)
845                     {
846                         using PropertyValue setCropValue = new PropertyValue(true);
847                         UpdateImage(ImageVisualProperty.CropToMask, setCropValue);
848                     }
849                 }
850                 setValue?.Dispose();
851             }
852         }
853
854
855         /// <summary>
856         ///  Whether to crop image to mask or scale mask to fit image.
857         /// </summary>
858         /// <since_tizen> 6 </since_tizen>
859         public bool CropToMask
860         {
861             get
862             {
863                 return (bool)GetValue(CropToMaskProperty);
864             }
865             set
866             {
867                 SetValue(CropToMaskProperty, value);
868                 NotifyPropertyChanged();
869             }
870         }
871         private bool InternalCropToMask
872         {
873             get
874             {
875                 bool ret = false;
876
877                 PropertyValue cropToMask = GetCachedImageVisualProperty(ImageVisualProperty.CropToMask);
878                 cropToMask?.Get(out ret);
879                 cropToMask?.Dispose();
880
881                 return ret;
882             }
883             set
884             {
885                 PropertyValue setValue = new PropertyValue(value);
886                 UpdateImage(ImageVisualProperty.CropToMask, setValue);
887                 setValue?.Dispose();
888             }
889         }
890
891         /// <summary>
892         /// Actions property value for Reload image.
893         /// </summary>
894         internal static readonly int ActionReload = Interop.ImageView.ImageVisualActionReloadGet();
895
896         /// <summary>
897         /// Actions property value to Play animated images.
898         /// </summary>
899         internal static readonly int ActionPlay = Interop.AnimatedImageView.AnimatedImageVisualActionPlayGet();
900
901         /// <summary>
902         /// Actions property value to Pause animated images.
903         /// </summary>
904         internal static readonly int ActionPause = Interop.AnimatedImageView.AnimatedImageVisualActionPauseGet();
905
906         /// <summary>
907         /// Actions property value to Stop animated images.
908         /// </summary>
909         internal static readonly int ActionStop = Interop.AnimatedImageView.AnimatedImageVisualActionStopGet();
910
911         internal VisualFittingModeType ConvertFittingModetoVisualFittingMode(FittingModeType value)
912         {
913             switch (value)
914             {
915                 case FittingModeType.ShrinkToFit:
916                     return VisualFittingModeType.FitKeepAspectRatio;
917                 case FittingModeType.ScaleToFill:
918                     return VisualFittingModeType.OverFitKeepAspectRatio;
919                 case FittingModeType.Center:
920                     return VisualFittingModeType.Center;
921                 case FittingModeType.Fill:
922                     return VisualFittingModeType.Fill;
923                 case FittingModeType.FitHeight:
924                     return VisualFittingModeType.FitHeight;
925                 case FittingModeType.FitWidth:
926                     return VisualFittingModeType.FitWidth;
927                 default:
928                     return VisualFittingModeType.Fill;
929             }
930         }
931
932         internal FittingModeType ConvertVisualFittingModetoFittingMode(VisualFittingModeType value)
933         {
934             switch (value)
935             {
936                 case VisualFittingModeType.FitKeepAspectRatio:
937                     return FittingModeType.ShrinkToFit;
938                 case VisualFittingModeType.OverFitKeepAspectRatio:
939                     return FittingModeType.ScaleToFill;
940                 case VisualFittingModeType.Center:
941                     return FittingModeType.Center;
942                 case VisualFittingModeType.Fill:
943                     return FittingModeType.Fill;
944                 case VisualFittingModeType.FitHeight:
945                     return FittingModeType.FitHeight;
946                 case VisualFittingModeType.FitWidth:
947                     return FittingModeType.FitWidth;
948                 default:
949                     return FittingModeType.ShrinkToFit;
950             }
951         }
952
953         internal override LayoutItem CreateDefaultLayout()
954         {
955             return new ImageLayout();
956         }
957
958         /// <summary>
959         /// Gets or sets fitting options used when resizing images to fit.<br />
960         /// If not supplied, the default is FittingModeType.Fill.<br />
961         /// For normal quad images only.<br />
962         /// Optional.
963         /// </summary>
964         /// <since_tizen> 6 </since_tizen>
965         [EditorBrowsable(EditorBrowsableState.Never)]
966         public FittingModeType FittingMode
967         {
968             get
969             {
970                 return (FittingModeType)GetValue(FittingModeProperty);
971             }
972             set
973             {
974                 SetValue(FittingModeProperty, value);
975                 NotifyPropertyChanged();
976             }
977         }
978
979         private FittingModeType InternalFittingMode
980         {
981             get
982             {
983                 int ret = (int)VisualFittingModeType.Fill;
984
985                 PropertyValue fittingMode = GetCachedImageVisualProperty(Visual.Property.VisualFittingMode);
986                 fittingMode?.Get(out ret);
987                 fittingMode?.Dispose();
988
989                 return ConvertVisualFittingModetoFittingMode((VisualFittingModeType)ret);
990             }
991             set
992             {
993                 VisualFittingModeType ret = ConvertFittingModetoVisualFittingMode(value);
994                 PropertyValue setValue = new PropertyValue((int)ret);
995                 UpdateImage(Visual.Property.VisualFittingMode, setValue);
996                 setValue?.Dispose();
997             }
998         }
999
1000         /// <summary>
1001         /// Gets or sets the desired image width.<br />
1002         /// If not specified, the actual image width is used.<br />
1003         /// For normal quad images only.<br />
1004         /// Optional.
1005         /// </summary>
1006         /// <since_tizen> 6 </since_tizen>
1007         [EditorBrowsable(EditorBrowsableState.Never)]
1008         public int DesiredWidth
1009         {
1010             get
1011             {
1012                 return (int)GetValue(DesiredWidthProperty);
1013             }
1014             set
1015             {
1016                 SetValue(DesiredWidthProperty, value);
1017                 NotifyPropertyChanged();
1018             }
1019         }
1020         private int InternalDesiredWidth
1021         {
1022             get
1023             {
1024                 // Sync as current properties only if both _desired_width and _desired_height are setuped.
1025                 if (_desired_width != -1 && _desired_height != -1)
1026                 {
1027                     UpdateImage();
1028                 }
1029                 PropertyValue desirewidth = GetCachedImageVisualProperty(ImageVisualProperty.DesiredWidth);
1030                 desirewidth?.Get(out _desired_width);
1031                 desirewidth?.Dispose();
1032
1033                 return _desired_width;
1034             }
1035             set
1036             {
1037                 if (_desired_width != value)
1038                 {
1039                     _desired_width = value;
1040                     PropertyValue setValue = new PropertyValue(value);
1041                     UpdateImage(ImageVisualProperty.DesiredWidth, setValue, false);
1042                     setValue?.Dispose();
1043                 }
1044             }
1045         }
1046
1047         /// <summary>
1048         /// Gets or sets the desired image height.<br />
1049         /// If not specified, the actual image height is used.<br />
1050         /// For normal quad images only.<br />
1051         /// Optional.
1052         /// </summary>
1053         /// <since_tizen> 6 </since_tizen>
1054         [EditorBrowsable(EditorBrowsableState.Never)]
1055         public int DesiredHeight
1056         {
1057             get
1058             {
1059                 return (int)GetValue(DesiredHeightProperty);
1060             }
1061             set
1062             {
1063                 SetValue(DesiredHeightProperty, value);
1064                 NotifyPropertyChanged();
1065             }
1066         }
1067         private int InternalDesiredHeight
1068         {
1069             get
1070             {
1071                 // Sync as current properties only if both _desired_width and _desired_height are setuped.
1072                 if (_desired_width != -1 && _desired_height != -1)
1073                 {
1074                     UpdateImage();
1075                 }
1076                 PropertyValue desireheight = GetCachedImageVisualProperty(ImageVisualProperty.DesiredHeight);
1077                 desireheight?.Get(out _desired_height);
1078                 desireheight?.Dispose();
1079
1080                 return _desired_height;
1081             }
1082             set
1083             {
1084                 if (_desired_height != value)
1085                 {
1086                     _desired_height = value;
1087                     PropertyValue setValue = new PropertyValue(value);
1088                     UpdateImage(ImageVisualProperty.DesiredHeight, setValue, false);
1089                     setValue?.Dispose();
1090                 }
1091             }
1092         }
1093
1094         /// <summary>
1095         /// Gets or sets ReleasePolicy for image.<br />
1096         /// If not supplied, the default is ReleasePolicyType.Detached.<br />
1097         /// </summary>
1098         [EditorBrowsable(EditorBrowsableState.Never)]
1099         public ReleasePolicyType ReleasePolicy
1100         {
1101             get
1102             {
1103                 return (ReleasePolicyType)GetValue(ReleasePolicyProperty);
1104             }
1105             set
1106             {
1107                 SetValue(ReleasePolicyProperty, value);
1108                 NotifyPropertyChanged();
1109             }
1110         }
1111
1112         private ReleasePolicyType InternalReleasePolicy
1113         {
1114             get
1115             {
1116                 int ret = (int)ReleasePolicyType.Detached;
1117
1118                 PropertyValue releasePoli = GetCachedImageVisualProperty(ImageVisualProperty.ReleasePolicy);
1119                 releasePoli?.Get(out ret);
1120                 releasePoli?.Dispose();
1121
1122                 return (ReleasePolicyType)ret;
1123             }
1124             set
1125             {
1126                 PropertyValue setValue = new PropertyValue((int)value);
1127                 UpdateImage(ImageVisualProperty.ReleasePolicy, setValue);
1128                 setValue?.Dispose();
1129             }
1130         }
1131
1132         /// <summary>
1133         /// Gets or sets the wrap mode for the u coordinate.<br />
1134         /// It decides how the texture should be sampled when the u coordinate exceeds the range of 0.0 to 1.0.<br />
1135         /// If not specified, the default is WrapModeType.Default(CLAMP).<br />
1136         /// For normal quad images only.<br />
1137         /// Optional.
1138         /// </summary>
1139         /// <since_tizen> 6 </since_tizen>
1140         [EditorBrowsable(EditorBrowsableState.Never)]
1141         public WrapModeType WrapModeU
1142         {
1143             get
1144             {
1145                 return (WrapModeType)GetValue(WrapModeUProperty);
1146             }
1147             set
1148             {
1149                 SetValue(WrapModeUProperty, value);
1150                 NotifyPropertyChanged();
1151             }
1152         }
1153
1154         private WrapModeType InternalWrapModeU
1155         {
1156             get
1157             {
1158                 int ret = (int)WrapModeType.Default;
1159
1160                 PropertyValue wrapModeU = GetCachedImageVisualProperty(ImageVisualProperty.WrapModeU);
1161                 wrapModeU?.Get(out ret);
1162                 wrapModeU?.Dispose();
1163
1164                 return (WrapModeType)ret;
1165             }
1166             set
1167             {
1168                 PropertyValue setValue = new PropertyValue((int)value);
1169                 UpdateImage(ImageVisualProperty.WrapModeU, setValue);
1170                 setValue?.Dispose();
1171             }
1172         }
1173
1174         /// <summary>
1175         /// Gets or sets the wrap mode for the v coordinate.<br />
1176         /// It decides how the texture should be sampled when the v coordinate exceeds the range of 0.0 to 1.0.<br />
1177         /// 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 />
1178         /// If not specified, the default is WrapModeType.Default(CLAMP).<br />
1179         /// For normal quad images only.
1180         /// Optional.
1181         /// </summary>
1182         /// <since_tizen> 6 </since_tizen>
1183         [EditorBrowsable(EditorBrowsableState.Never)]
1184         public WrapModeType WrapModeV
1185         {
1186             get
1187             {
1188                 return (WrapModeType)GetValue(WrapModeVProperty);
1189             }
1190             set
1191             {
1192                 SetValue(WrapModeVProperty, value);
1193                 NotifyPropertyChanged();
1194             }
1195         }
1196
1197         private WrapModeType InternalWrapModeV
1198         {
1199             get
1200             {
1201                 int ret = (int)WrapModeType.Default;
1202
1203                 PropertyValue wrapModeV = GetCachedImageVisualProperty(ImageVisualProperty.WrapModeV);
1204                 wrapModeV?.Get(out ret);
1205                 wrapModeV?.Dispose();
1206
1207                 return (WrapModeType)ret;
1208             }
1209             set
1210             {
1211                 PropertyValue setValue = new PropertyValue((int)value);
1212                 UpdateImage(ImageVisualProperty.WrapModeV, setValue);
1213                 setValue?.Dispose();
1214             }
1215         }
1216
1217         /// <summary>
1218         /// Gets or sets the mode to adjust view size to preserve the aspect ratio of the image resource.
1219         /// </summary>
1220         /// <remarks>
1221         /// This is false by default.
1222         /// If this is set to be true, then the width or height value, which is not set by user explicitly, can be changed automatically
1223         /// to preserve the aspect ratio of the image resource.
1224         /// AdjustViewSize works only if ImageView is added to a View having Layout.
1225         /// e.g. If the image resource size is (100, 100), then the ImageView requests size (100, 100) to its parent layout by default.
1226         ///      If the ImageView's HeightSpecification is 50 and AdjustViewSize is true, then the ImageView requests size (50, 50) instead of (100, 50).
1227         /// </remarks>
1228         /// <since_tizen> 9 </since_tizen>
1229         public bool AdjustViewSize
1230         {
1231             get
1232             {
1233                 return (bool)GetValue(AdjustViewSizeProperty);
1234             }
1235             set
1236             {
1237                 SetValue(AdjustViewSizeProperty, value);
1238                 NotifyPropertyChanged();
1239             }
1240         }
1241         private bool adjustViewSize = false;
1242
1243         /// <summary>
1244         /// ImageView PlaceHolderUrl, type string.
1245         /// This is one of mandatory property. Even if not set or null set, it sets empty string ("") internally.
1246         /// When it is set as null, it gives empty string ("") to be read.
1247         /// </summary>
1248         /// <since_tizen> 11 </since_tizen>
1249         [EditorBrowsable(EditorBrowsableState.Never)]
1250         public string PlaceHolderUrl
1251         {
1252             get
1253             {
1254                 return (string)GetValue(PlaceHolderUrlProperty);
1255             }
1256             set
1257             {
1258                 SetValue(PlaceHolderUrlProperty, value);
1259                 NotifyPropertyChanged();
1260             }
1261         }
1262
1263         /// <summary>
1264         /// Gets or sets whether the image use TransitionEffect or not<br />
1265         /// </summary>
1266         /// <since_tizen> 11 </since_tizen>
1267         [EditorBrowsable(EditorBrowsableState.Never)]
1268         public bool TransitionEffect
1269         {
1270             get
1271             {
1272                 return (bool)GetValue(TransitionEffectProperty);
1273             }
1274             set
1275             {
1276                 SetValue(TransitionEffectProperty, value);
1277                 NotifyPropertyChanged();
1278             }
1279         }
1280
1281         internal Selector<string> ResourceUrlSelector
1282         {
1283             get => GetSelector<string>(resourceUrlSelector, ImageView.ResourceUrlProperty);
1284             set
1285             {
1286                 resourceUrlSelector?.Reset(this);
1287                 if (value == null) return;
1288
1289                 if (value.HasAll()) SetResourceUrl(value.All);
1290                 else resourceUrlSelector = new TriggerableSelector<string>(this, value, SetResourceUrl, true);
1291             }
1292         }
1293
1294         /// <summary>
1295         /// Get attributes, it is abstract function and must be override.
1296         /// </summary>
1297         [EditorBrowsable(EditorBrowsableState.Never)]
1298         protected override ViewStyle CreateViewStyle()
1299         {
1300             return new ImageViewStyle();
1301         }
1302
1303         internal void SetImage(string url, Uint16Pair size)
1304         {
1305             if (url.Contains(".json"))
1306             {
1307                 Tizen.Log.Fatal("NUI", "[ERROR] Do not set lottie file in ImageView! This is temporary checking, will be removed soon!");
1308                 return;
1309             }
1310
1311             Interop.ImageView.SetImage(SwigCPtr, ConvertResourceUrl(ref url), Uint16Pair.getCPtr(size));
1312             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
1313
1314             _resourceUrl = url;
1315             _desired_width = size?.GetWidth() ?? -1;
1316             _desired_height = size?.GetHeight() ?? -1;
1317
1318             // Update cached property. Note that we should not re-create new visual.
1319             using (PropertyValue urlValue = new PropertyValue(_resourceUrl))
1320             {
1321                 UpdateImage(ImageVisualProperty.URL, urlValue, false);
1322             }
1323             using (PropertyValue desiredWidthValue = new PropertyValue(_desired_width))
1324             {
1325                 UpdateImage(ImageVisualProperty.DesiredWidth, desiredWidthValue, false);
1326             }
1327             using (PropertyValue desiredHeightValue = new PropertyValue(_desired_height))
1328             {
1329                 UpdateImage(ImageVisualProperty.DesiredWidth, desiredHeightValue, false);
1330             }
1331             imagePropertyUpdatedFlag = false;
1332         }
1333
1334         internal ViewResourceReadySignal ResourceReadySignal(View view)
1335         {
1336             ViewResourceReadySignal ret = new ViewResourceReadySignal(Interop.View.ResourceReadySignal(View.getCPtr(view)), false);
1337             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
1338             return ret;
1339         }
1340
1341         internal override void ApplyCornerRadius()
1342         {
1343             base.ApplyCornerRadius();
1344
1345             if (backgroundExtraData == null) return;
1346
1347
1348             // Update corner radius properties to image by ActionUpdateProperty
1349             if (backgroundExtraData.CornerRadius != null)
1350             {
1351                 Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.CornerRadius, Vector4.getCPtr(backgroundExtraData.CornerRadius));
1352             }
1353             Interop.View.InternalUpdateVisualPropertyInt(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.CornerRadiusPolicy, (int)backgroundExtraData.CornerRadiusPolicy);
1354         }
1355
1356         internal override void ApplyBorderline()
1357         {
1358             base.ApplyBorderline();
1359
1360             if (backgroundExtraData == null) return;
1361
1362
1363             // Update borderline properties to image by ActionUpdateProperty
1364             Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineWidth, backgroundExtraData.BorderlineWidth);
1365             Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineColor, Vector4.getCPtr(backgroundExtraData.BorderlineColor ?? Color.Black));
1366             Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineOffset, backgroundExtraData.BorderlineOffset);
1367         }
1368
1369         internal ResourceLoadingStatusType GetResourceStatus()
1370         {
1371             return (ResourceLoadingStatusType)Interop.View.GetVisualResourceStatus(this.SwigCPtr, Property.IMAGE);
1372         }
1373
1374         /// <summary>
1375         /// you can override it to clean-up your own resources.
1376         /// </summary>
1377         /// <param name="type">DisposeTypes</param>
1378         /// <since_tizen> 3 </since_tizen>
1379         protected override void Dispose(DisposeTypes type)
1380         {
1381             if (disposed)
1382             {
1383                 return;
1384             }
1385
1386             internalPixelArea?.Dispose();
1387
1388             if (type == DisposeTypes.Explicit)
1389             {
1390                 //Called by User
1391                 //Release your own managed resources here.
1392                 //You should release all of your own disposable objects here.
1393                 _border?.Dispose();
1394                 _border = null;
1395                 borderSelector?.Reset(this);
1396                 resourceUrlSelector?.Reset(this);
1397                 imagePropertyUpdatedFlag = false;
1398                 if (imagePropertyUpdateProcessAttachedFlag)
1399                 {
1400                     ProcessorController.Instance.ProcessorOnceEvent -= UpdateImage;
1401                     imagePropertyUpdateProcessAttachedFlag = false;
1402                 }
1403                 cachedImagePropertyMap?.Dispose();
1404                 cachedImagePropertyMap = null;
1405             }
1406
1407             base.Dispose(type);
1408         }
1409
1410         /// This will not be public opened.
1411         [EditorBrowsable(EditorBrowsableState.Never)]
1412         protected override void ReleaseSwigCPtr(System.Runtime.InteropServices.HandleRef swigCPtr)
1413         {
1414             Interop.ImageView.DeleteImageView(swigCPtr);
1415         }
1416
1417         // Callback for View ResourceReady signal
1418         private void OnResourceReady(IntPtr data)
1419         {
1420             if (!CheckResourceReady())
1421             {
1422                 return;
1423             }
1424
1425             ResourceReadyEventArgs e = new ResourceReadyEventArgs();
1426             if (data != null)
1427             {
1428                 e.View = Registry.GetManagedBaseHandleFromNativePtr(data) as View;
1429             }
1430
1431             if (_resourceReadyEventHandler != null)
1432             {
1433                 _resourceReadyEventHandler(this, e);
1434             }
1435         }
1436
1437         private void SetResourceUrl(string value)
1438         {
1439             if (_resourceUrl != ConvertResourceUrl(ref value))
1440             {
1441                 _resourceUrl = value;
1442                 if (string.IsNullOrEmpty(_resourceUrl))
1443                 {
1444                     // Special case. If we set ResourceUrl as empty, Unregist visual.
1445                     RemoveImage();
1446                 }
1447                 else
1448                 {
1449                     using (PropertyValue setValue = new PropertyValue(value))
1450                     {
1451                         UpdateImage(ImageVisualProperty.URL, setValue);
1452                     }
1453                     // Special case. If we set GeneratedUrl, or FastTrackUploading, Create ImageVisual synchronously.
1454                     if (value.StartsWith("dali://") || value.StartsWith("enbuf://") || _fastTrackUploading)
1455                     {
1456                         UpdateImage();
1457                     }
1458                 }
1459             }
1460         }
1461
1462         private void SetBorder(Rectangle value)
1463         {
1464             if (value == null)
1465             {
1466                 return;
1467             }
1468             if (_border != value)
1469             {
1470                 _border = new Rectangle(value);
1471                 UpdateImage(NpatchImageVisualProperty.Border, new PropertyValue(_border));
1472             }
1473         }
1474
1475         /// <summary>
1476         /// Unregist image visual directly. After this operation, we cannot get any properties from Image property.
1477         /// </summary>
1478         private void RemoveImage()
1479         {
1480             // If previous resourceUrl was already empty, we don't need to do anything. just ignore.
1481             // Unregist and detach process only if previous resourceUrl was not empty
1482             string currentResourceUrl = "";
1483             PropertyValue currentResourceUrlValue = GetCachedImageVisualProperty(ImageVisualProperty.URL);
1484             if ((currentResourceUrlValue?.Get(out currentResourceUrl) ?? false) && !string.IsNullOrEmpty(currentResourceUrl))
1485             {
1486                 PropertyValue emptyValue = new PropertyValue();
1487
1488                 // Remove current registed Image.
1489                 SetProperty(ImageView.Property.IMAGE, emptyValue);
1490
1491                 // Image visual is not exist anymore. We should ignore lazy UpdateImage
1492                 imagePropertyUpdatedFlag = false;
1493                 if (imagePropertyUpdateProcessAttachedFlag)
1494                 {
1495                     ProcessorController.Instance.ProcessorOnceEvent -= UpdateImage;
1496                     imagePropertyUpdateProcessAttachedFlag = false;
1497                 }
1498                 // Update resourceUrl as empty value
1499                 cachedImagePropertyMap[ImageVisualProperty.URL] = emptyValue;
1500
1501                 emptyValue?.Dispose();
1502             }
1503             currentResourceUrlValue?.Dispose();
1504         }
1505
1506         /// <summary>
1507         /// Lazy call to UpdateImage.
1508         /// Collect Properties need to be update, and set properties that starts the Processing.
1509         ///
1510         /// If you want to update cachedImagePropertyMap, but don't want to request new visual creation, make requiredVisualCreation value as false.
1511         /// (Example : if we change SynchronousLoading property from 'true' to 'false', or if we call this function during UpdateImage)
1512         /// </summary>
1513         [EditorBrowsable(EditorBrowsableState.Never)]
1514         protected virtual void UpdateImage(int key, PropertyValue value, bool requiredVisualCreation = true)
1515         {
1516             // Update image property map value as inputed value.
1517             if (key != 0)
1518             {
1519                 if (!HasBody())
1520                 {
1521                     // Throw exception if ImageView is disposed.
1522                     throw new global::System.InvalidOperationException("[NUI][ImageVIew] Someone try to change disposed ImageView's property.\n");
1523                 }
1524
1525                 if (cachedImagePropertyMap == null)
1526                 {
1527                     cachedImagePropertyMap = new PropertyMap();
1528                 }
1529
1530                 // To optimization, we don't check URL duplicate case. We already checked before.
1531                 if (key != ImageVisualProperty.URL)
1532                 {
1533                     using (PropertyValue oldValue = GetCachedImageVisualProperty(key))
1534                     {
1535                         if (oldValue != null && oldValue.EqualTo(value))
1536                         {
1537                             // Ignore UpdateImage query when we try to update equality value.
1538                             return;
1539                         }
1540                     }
1541                 }
1542                 imagePropertyUpdatedFlag = true;
1543                 cachedImagePropertyMap[key] = value;
1544
1545                 // Lazy update only if visual creation required, and _resourceUrl is not empty, and ProcessAttachedFlag is false.
1546                 if (requiredVisualCreation && !string.IsNullOrEmpty(_resourceUrl) && !imagePropertyUpdateProcessAttachedFlag)
1547                 {
1548                     imagePropertyUpdateProcessAttachedFlag = true;
1549                     ProcessorController.Instance.ProcessorOnceEvent += UpdateImage;
1550                     // Call process hardly.
1551                     ProcessorController.Instance.Awake();
1552                 }
1553             }
1554         }
1555
1556         /// <summary>
1557         /// Callback function to Lazy UpdateImage.
1558         /// </summary>
1559         private void UpdateImage(object source, EventArgs e)
1560         {
1561             // Note : To allow event attachment during UpdateImage, let we make flag as false before call UpdateImage().
1562             imagePropertyUpdateProcessAttachedFlag = false;
1563             UpdateImage();
1564         }
1565
1566         /// <summary>
1567         /// Update image-relative properties synchronously.
1568         /// After call this API, All image properties updated.
1569         /// </summary>
1570         /// <remarks>
1571         /// Current version ImageView property update asynchronously.
1572         /// If you want to guarantee that ImageView property setuped,
1573         /// Please call this ImageView.UpdateImage() API.
1574         /// </remarks>
1575         [EditorBrowsable(EditorBrowsableState.Never)]
1576         protected virtual void UpdateImage()
1577         {
1578             if (!imagePropertyUpdatedFlag) return;
1579
1580             imagePropertyUpdatedFlag = false;
1581
1582             if (cachedImagePropertyMap == null)
1583             {
1584                 cachedImagePropertyMap = new PropertyMap();
1585             }
1586
1587             // Checkup the cached visual type is AnimatedImage.
1588             // It is trick to know that this code is running on AnimatedImageView.UpdateImage() with resourceURLs or not.
1589             int visualType = (int)Visual.Type.Invalid;
1590             if (!((GetCachedImageVisualProperty(Visual.Property.Type)?.Get(out visualType) ?? false) && (visualType == (int)Visual.Type.AnimatedImage)))
1591             {
1592                 // If ResourceUrl is not setuped, don't set property. fast return.
1593                 if (string.IsNullOrEmpty(_resourceUrl))
1594                 {
1595                     return;
1596                 }
1597                 if (_border == null)
1598                 {
1599                     PropertyValue image = new PropertyValue((int)Visual.Type.Image);
1600                     cachedImagePropertyMap[Visual.Property.Type] = image;
1601                     image?.Dispose();
1602                 }
1603                 else
1604                 {
1605                     PropertyValue nPatch = new PropertyValue((int)Visual.Type.NPatch);
1606                     cachedImagePropertyMap[Visual.Property.Type] = nPatch;
1607                     nPatch?.Dispose();
1608                     PropertyValue border = new PropertyValue(_border);
1609                     cachedImagePropertyMap[NpatchImageVisualProperty.Border] = border;
1610                     border?.Dispose();
1611                 }
1612             }
1613
1614             if (backgroundExtraData != null && backgroundExtraData.CornerRadius != null)
1615             {
1616                 using (var cornerRadius = new PropertyValue(backgroundExtraData.CornerRadius))
1617                 using (var cornerRadiusPolicy = new PropertyValue((int)backgroundExtraData.CornerRadiusPolicy))
1618                 {
1619                     cachedImagePropertyMap[Visual.Property.CornerRadius] = cornerRadius;
1620                     cachedImagePropertyMap[Visual.Property.CornerRadiusPolicy] = new PropertyValue((int)(backgroundExtraData.CornerRadiusPolicy));
1621                 }
1622             }
1623
1624             if (backgroundExtraData != null && backgroundExtraData.BorderlineWidth > 0.0f)
1625             {
1626                 using (var borderlineWidth = new PropertyValue(backgroundExtraData.BorderlineWidth))
1627                 using (var borderlineColor = new PropertyValue(backgroundExtraData.BorderlineColor))
1628                 using (var borderlineOffset = new PropertyValue(backgroundExtraData.BorderlineOffset))
1629                 {
1630                     cachedImagePropertyMap[Visual.Property.BorderlineWidth] = borderlineWidth;
1631                     cachedImagePropertyMap[Visual.Property.BorderlineColor] = borderlineColor;
1632                     cachedImagePropertyMap[Visual.Property.BorderlineOffset] = borderlineOffset;
1633                 }
1634             }
1635
1636             // Do Fitting Buffer when desired dimension is set
1637             // TODO : Couldn't we do this job in dali-engine side.
1638             if (_desired_width != -1 && _desired_height != -1)
1639             {
1640                 if (_resourceUrl != null)
1641                 {
1642                     Size2D imageSize = ImageLoader.GetOriginalImageSize(_resourceUrl, true);
1643                     if (imageSize.Height > 0 && imageSize.Width > 0 && _desired_width > 0 && _desired_height > 0)
1644                     {
1645                         int adjustedDesiredWidth, adjustedDesiredHeight;
1646                         float aspectOfDesiredSize = (float)_desired_height / (float)_desired_width;
1647                         float aspectOfImageSize = (float)imageSize.Height / (float)imageSize.Width;
1648                         if (aspectOfImageSize > aspectOfDesiredSize)
1649                         {
1650                             adjustedDesiredWidth = _desired_width;
1651                             adjustedDesiredHeight = imageSize.Height * _desired_width / imageSize.Width;
1652                         }
1653                         else
1654                         {
1655                             adjustedDesiredWidth = imageSize.Width * _desired_height / imageSize.Height;
1656                             adjustedDesiredHeight = _desired_height;
1657                         }
1658
1659                         PropertyValue returnWidth = new PropertyValue(adjustedDesiredWidth);
1660                         cachedImagePropertyMap[ImageVisualProperty.DesiredWidth] = returnWidth;
1661                         returnWidth?.Dispose();
1662                         PropertyValue returnHeight = new PropertyValue(adjustedDesiredHeight);
1663                         cachedImagePropertyMap[ImageVisualProperty.DesiredHeight] = returnHeight;
1664                         returnHeight?.Dispose();
1665                         PropertyValue scaleToFit = new PropertyValue((int)FittingModeType.ScaleToFill);
1666                         cachedImagePropertyMap[ImageVisualProperty.FittingMode] = scaleToFit;
1667                         scaleToFit?.Dispose();
1668                     }
1669                     imageSize?.Dispose();
1670                 }
1671             }
1672
1673             UpdateImageMap();
1674         }
1675
1676         /// <summary>
1677         /// Merge our collected properties, and set IMAGE property internally.
1678         /// </summary>
1679         private void UpdateImageMap()
1680         {
1681             // Note : We can't use ImageView.Image property here. Because That property call UpdateImage internally.
1682             using (PropertyMap imageMap = new PropertyMap())
1683             {
1684                 using (PropertyValue returnValue = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE))
1685                 {
1686                     returnValue?.Get(imageMap);
1687                 }
1688                 if (cachedImagePropertyMap != null)
1689                 {
1690                     imageMap?.Merge(cachedImagePropertyMap);
1691                 }
1692                 using (PropertyValue setValue = new PropertyValue(imageMap))
1693                 {
1694                     SetProperty(ImageView.Property.IMAGE, setValue);
1695                 }
1696
1697                 // Update cached image property.
1698                 MergeCachedImageVisualProperty(imageMap);
1699             }
1700         }
1701
1702         /// <summary>
1703         /// Get image visual property by key.
1704         /// If we found value in local Cached result, return that.
1705         /// Else, get synced native map and return that.
1706         /// If there is no matched value, return null.
1707         /// </summary>
1708         [EditorBrowsable(EditorBrowsableState.Never)]
1709         protected virtual PropertyValue GetImageVisualProperty(int key)
1710         {
1711             PropertyValue ret = GetCachedImageVisualProperty(key);
1712             if (ret == null)
1713             {
1714                 // If we cannot find result form cached map, Get value from native engine.
1715                 ret = Image?.Find(key);
1716             }
1717             return ret;
1718         }
1719
1720         /// <summary>
1721         /// Get image visual property from NUI cached image map by key.
1722         /// If there is no matched value, return null.
1723         /// </summary>
1724         [EditorBrowsable(EditorBrowsableState.Never)]
1725         protected virtual PropertyValue GetCachedImageVisualProperty(int key)
1726         {
1727             return cachedImagePropertyMap?.Find(key);
1728         }
1729
1730         /// <summary>
1731         /// Update NUI cached image visual property map by inputed property map.
1732         /// </summary>
1733         /// <remarks>
1734         /// For performance issue, we will collect only "cachedImagePropertyKeyList" hold.
1735         /// </remarks>
1736         [EditorBrowsable(EditorBrowsableState.Never)]
1737         protected virtual void MergeCachedImageVisualProperty(PropertyMap map)
1738         {
1739             if (map == null) return;
1740             if (cachedImagePropertyMap == null)
1741             {
1742                 cachedImagePropertyMap = new PropertyMap();
1743             }
1744             foreach (var key in cachedImagePropertyKeyList)
1745             {
1746                 PropertyValue value = map.Find(key);
1747                 if (value != null)
1748                 {
1749                     // Update-or-Insert new value
1750                     cachedImagePropertyMap[key] = value;
1751                     if (key == ImageVisualProperty.URL)
1752                     {
1753                         // Special case. If key is Url, update _resourceUrl here.
1754                         value.Get(out _resourceUrl);
1755                     }
1756                 }
1757             }
1758         }
1759
1760         /// <summary>
1761         /// GetNaturalSize() should be guaranteed that ResourceUrl property setuped.
1762         /// So before get base.GetNaturalSize(), we should synchronous image properties
1763         /// </summary>
1764         internal override Vector3 GetNaturalSize()
1765         {
1766             // Sync as current properties
1767             UpdateImage();
1768             return base.GetNaturalSize();
1769         }
1770
1771         [EditorBrowsable(EditorBrowsableState.Never)]
1772         protected override bool CheckResourceReady()
1773         {
1774             // If we have some properties to be updated, this signal is old thing.
1775             // We need to ignore current signal, and wait next.
1776             return !(imagePropertyUpdateProcessAttachedFlag && imagePropertyUpdatedFlag);
1777         }
1778
1779         private void OnResourceLoaded(IntPtr view)
1780         {
1781             if (!CheckResourceReady())
1782             {
1783                 return;
1784             }
1785             ResourceLoadedEventArgs e = new ResourceLoadedEventArgs();
1786             e.Status = (ResourceLoadingStatusType)Interop.View.GetVisualResourceStatus(this.SwigCPtr, Property.IMAGE);
1787
1788             if (_resourceLoadedEventHandler != null)
1789             {
1790                 _resourceLoadedEventHandler(this, e);
1791             }
1792         }
1793
1794         /// <summary>
1795         /// Event arguments of resource ready.
1796         /// </summary>
1797         /// <since_tizen> 3 </since_tizen>
1798         public class ResourceReadyEventArgs : EventArgs
1799         {
1800             private View _view;
1801
1802             /// <summary>
1803             /// The view whose resource is ready.
1804             /// </summary>
1805             /// <since_tizen> 3 </since_tizen>
1806             public View View
1807             {
1808                 get
1809                 {
1810                     return _view;
1811                 }
1812                 set
1813                 {
1814                     _view = value;
1815                 }
1816             }
1817         }
1818
1819         internal class ResourceLoadedEventArgs : EventArgs
1820         {
1821             private ResourceLoadingStatusType status = ResourceLoadingStatusType.Invalid;
1822             public ResourceLoadingStatusType Status
1823             {
1824                 get
1825                 {
1826                     return status;
1827                 }
1828                 set
1829                 {
1830                     status = value;
1831                 }
1832             }
1833         }
1834
1835         internal new class Property
1836         {
1837             internal static readonly int IMAGE = Interop.ImageView.ImageGet();
1838             internal static readonly int PreMultipliedAlpha = Interop.ImageView.PreMultipliedAlphaGet();
1839             internal static readonly int PixelArea = Interop.ImageView.PixelAreaGet();
1840             internal static readonly int PlaceHolderUrl = Interop.ImageView.PlaceHolderImageGet();
1841             internal static readonly int TransitionEffect = Interop.ImageView.TransitionEffectGet();
1842         }
1843
1844         private enum ImageType
1845         {
1846             /// <summary>
1847             /// For Normal Image.
1848             /// </summary>
1849             Normal = 0,
1850
1851             /// <summary>
1852             /// For normal image, with synchronous loading and orientation correction property
1853             /// </summary>
1854             Specific = 1,
1855
1856             /// <summary>
1857             /// For nine-patch image
1858             /// </summary>
1859             Npatch = 2,
1860         }
1861
1862         private void OnBorderChanged(int x, int y, int width, int height)
1863         {
1864             Border = new Rectangle(x, y, width, height);
1865         }
1866         private void OnPixelAreaChanged(float x, float y, float z, float w)
1867         {
1868             PixelArea = new RelativeVector4(x, y, z, w);
1869         }
1870
1871         private class ImageLayout : LayoutItem
1872         {
1873             /// <summary>
1874             /// Gets or sets the mode to adjust view size to preserve the aspect ratio of the image resource.
1875             /// If this is set to be true, then the width or height, which is not set by user explicitly, can be adjusted to preserve the aspect ratio of the image resource.
1876             /// </summary>
1877             [EditorBrowsable(EditorBrowsableState.Never)]
1878             public bool AdjustViewSize
1879             {
1880                 get
1881                 {
1882                     return (Owner as ImageView)?.AdjustViewSize ?? false;
1883                 }
1884                 set
1885                 {
1886                     if (Owner is ImageView imageView)
1887                     {
1888                         imageView.AdjustViewSize = value;
1889                     }
1890                 }
1891             }
1892
1893             /// <inheritdoc/>
1894             [EditorBrowsable(EditorBrowsableState.Never)]
1895             protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
1896             {
1897                 // To not change the view size by DALi
1898                 Owner.WidthResizePolicy = ResizePolicyType.Fixed;
1899                 Owner.HeightResizePolicy = ResizePolicyType.Fixed;
1900
1901                 float specWidth = widthMeasureSpec.Size.AsDecimal();
1902                 float specHeight = heightMeasureSpec.Size.AsDecimal();
1903                 float naturalWidth = Owner.NaturalSize.Width;
1904                 float naturalHeight = Owner.NaturalSize.Height;
1905                 float minWidth = Owner.MinimumSize.Width;
1906                 float maxWidth = Owner.MaximumSize.Width;
1907                 float minHeight = Owner.MinimumSize.Height;
1908                 float maxHeight = Owner.MaximumSize.Height;
1909                 float aspectRatio = (naturalWidth > 0) ? (naturalHeight / naturalWidth) : 0;
1910
1911                 // Assume that the new width and height are given from the view's suggested size by default.
1912                 float newWidth = Math.Min(Math.Max(naturalWidth, minWidth), (maxWidth < 0 ? Int32.MaxValue : maxWidth));
1913                 float newHeight = Math.Min(Math.Max(naturalHeight, minHeight), (maxHeight < 0 ? Int32.MaxValue : maxHeight));
1914
1915                 // The width and height measure specs are going to be used to set measured size.
1916                 // Mark that the measure specs are changed by default to update measure specs later.
1917                 bool widthSpecChanged = true;
1918                 bool heightSpecChanged = true;
1919
1920                 if (widthMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly)
1921                 {
1922                     newWidth = specWidth;
1923                     widthSpecChanged = false;
1924
1925                     if (heightMeasureSpec.Mode != MeasureSpecification.ModeType.Exactly)
1926                     {
1927                         if ((AdjustViewSize) && (aspectRatio > 0))
1928                         {
1929                             newHeight = newWidth * aspectRatio;
1930                         }
1931                     }
1932                 }
1933
1934                 if (heightMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly)
1935                 {
1936                     newHeight = specHeight;
1937                     heightSpecChanged = false;
1938
1939                     if (widthMeasureSpec.Mode != MeasureSpecification.ModeType.Exactly)
1940                     {
1941                         if ((AdjustViewSize) && (aspectRatio > 0))
1942                         {
1943                             newWidth = newHeight / aspectRatio;
1944                         }
1945                     }
1946                 }
1947
1948                 if (widthSpecChanged)
1949                 {
1950                     widthMeasureSpec = new MeasureSpecification(new LayoutLength(newWidth), MeasureSpecification.ModeType.Exactly);
1951                 }
1952
1953                 if (heightSpecChanged)
1954                 {
1955                     heightMeasureSpec = new MeasureSpecification(new LayoutLength(newHeight), MeasureSpecification.ModeType.Exactly);
1956                 }
1957
1958                 MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK;
1959                 MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK;
1960
1961                 SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(newWidth), widthMeasureSpec, childWidthState),
1962                                       ResolveSizeAndState(new LayoutLength(newHeight), heightMeasureSpec, childHeightState));
1963             }
1964         }
1965     }
1966 }