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