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