2 * Copyright(c) 2019 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.Collections.Generic;
19 using System.Runtime.InteropServices;
20 using System.ComponentModel;
21 using Tizen.NUI.Binding;
23 namespace Tizen.NUI.BaseComponents
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 />
30 /// <since_tizen> 3 </since_tizen>
31 public partial class ImageView : View
33 static ImageView() { }
35 private EventHandler<ResourceReadyEventArgs> _resourceReadyEventHandler;
36 private ResourceReadyEventCallbackType _resourceReadyEventCallback;
37 private EventHandler<ResourceLoadedEventArgs> _resourceLoadedEventHandler;
38 private _resourceLoadedCallbackType _resourceLoadedCallback;
40 // Collection of image-sensitive properties.
41 private static readonly List<int> cachedImagePropertyKeyList = new List<int> {
43 ImageVisualProperty.URL,
44 ImageVisualProperty.AlphaMaskURL,
45 ImageVisualProperty.CropToMask,
46 Visual.Property.VisualFittingMode,
47 ImageVisualProperty.DesiredWidth,
48 ImageVisualProperty.DesiredHeight,
49 ImageVisualProperty.ReleasePolicy,
50 ImageVisualProperty.WrapModeU,
51 ImageVisualProperty.WrapModeV,
52 ImageVisualProperty.SynchronousLoading,
53 Visual.Property.PremultipliedAlpha,
54 ImageVisualProperty.OrientationCorrection,
55 NpatchImageVisualProperty.Border,
56 NpatchImageVisualProperty.BorderOnly,
58 internal PropertyMap cachedImagePropertyMap;
59 internal bool imagePropertyUpdatedFlag = false;
61 private bool imagePropertyUpdateProcessAttachedFlag = false;
62 private Rectangle _border;
63 private string _resourceUrl = "";
64 private int _desired_width = -1;
65 private int _desired_height = -1;
66 private TriggerableSelector<string> resourceUrlSelector;
67 private TriggerableSelector<Rectangle> borderSelector;
69 #if NUI_PROPERTY_CHANGE_2
70 private RelativeVector4 internalPixelArea;
74 /// Creates an initialized ImageView.
76 /// <since_tizen> 3 </since_tizen>
77 public ImageView() : this(Interop.ImageView.New(), true)
79 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
82 /// This will be public opened in next release of tizen after ACR done. Before ACR, it is used as HiddenAPI (InhouseAPI).
83 [EditorBrowsable(EditorBrowsableState.Never)]
84 public ImageView(ViewStyle viewStyle) : this(Interop.ImageView.New(), true, viewStyle)
89 /// Creates an initialized ImageView with setting the status of shown or hidden.
91 /// <param name="shown">false : Not displayed (hidden), true : displayed (shown)</param>
92 /// This will be public opened in next release of tizen after ACR done. Before ACR, it is used as HiddenAPI (InhouseAPI).
93 [EditorBrowsable(EditorBrowsableState.Never)]
94 public ImageView(bool shown) : this(Interop.ImageView.New(), true)
96 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
101 /// Creates an initialized ImageView from a URL to an image resource.<br />
102 /// If the string is empty, ImageView will not display anything.<br />
104 /// <param name="url">The URL of the image resource to display.</param>
105 /// <since_tizen> 3 </since_tizen>
106 public ImageView(string url) : this(Interop.ImageView.New(url), true)
109 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
114 /// Creates an initialized ImageView from a URL to an image resource with setting shown or hidden.
116 /// <param name="url">The URL of the image resource to display.</param>
117 /// <param name="shown">false : Not displayed (hidden), true : displayed (shown)</param>
118 /// This will be public opened in next release of tizen after ACR done. Before ACR, it is used as HiddenAPI (InhouseAPI).
119 [EditorBrowsable(EditorBrowsableState.Never)]
120 public ImageView(string url, bool shown) : this(Interop.ImageView.New(url), true)
123 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
127 internal ImageView(string url, Uint16Pair size, bool shown = true) : this(Interop.ImageView.New(url, Uint16Pair.getCPtr(size)), true)
130 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
138 internal ImageView(global::System.IntPtr cPtr, bool cMemoryOwn, ViewStyle viewStyle, bool shown = true) : base(cPtr, cMemoryOwn, viewStyle)
146 internal ImageView(global::System.IntPtr cPtr, bool cMemoryOwn, bool shown = true) : base(cPtr, cMemoryOwn, null)
154 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
155 private delegate void ResourceReadyEventCallbackType(IntPtr data);
156 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
157 private delegate void _resourceLoadedCallbackType(IntPtr view);
160 /// An event for ResourceReady signal which can be used to subscribe or unsubscribe the event handler.<br />
161 /// This signal is emitted after all resources required by a control are loaded and ready.<br />
162 /// Most resources are only loaded when the control is placed on the stage.<br />
164 /// <since_tizen> 3 </since_tizen>
165 public event EventHandler<ResourceReadyEventArgs> ResourceReady
169 if (_resourceReadyEventHandler == null)
171 _resourceReadyEventCallback = OnResourceReady;
172 ViewResourceReadySignal resourceReadySignal = ResourceReadySignal(this);
173 resourceReadySignal?.Connect(_resourceReadyEventCallback);
174 resourceReadySignal?.Dispose();
177 _resourceReadyEventHandler += value;
182 _resourceReadyEventHandler -= value;
184 ViewResourceReadySignal resourceReadySignal = ResourceReadySignal(this);
185 if (_resourceReadyEventHandler == null && resourceReadySignal?.Empty() == false)
187 resourceReadySignal?.Disconnect(_resourceReadyEventCallback);
189 resourceReadySignal?.Dispose();
193 internal event EventHandler<ResourceLoadedEventArgs> ResourceLoaded
197 if (_resourceLoadedEventHandler == null)
199 _resourceLoadedCallback = OnResourceLoaded;
200 ViewResourceReadySignal resourceReadySignal = this.ResourceReadySignal(this);
201 resourceReadySignal?.Connect(_resourceLoadedCallback);
202 resourceReadySignal?.Dispose();
205 _resourceLoadedEventHandler += value;
209 _resourceLoadedEventHandler -= value;
210 ViewResourceReadySignal resourceReadySignal = this.ResourceReadySignal(this);
211 if (_resourceLoadedEventHandler == null && resourceReadySignal?.Empty() == false)
213 resourceReadySignal?.Disconnect(_resourceLoadedCallback);
215 resourceReadySignal?.Dispose();
220 /// Enumeration for LoadingStatus of image.
222 /// <since_tizen> 5 </since_tizen>
223 public enum LoadingStatusType
226 /// Loading preparing status.
228 /// <since_tizen> 5 </since_tizen>
231 /// Loading ready status.
233 /// <since_tizen> 5 </since_tizen>
236 /// Loading failed status.
238 /// <since_tizen> 5 </since_tizen>
243 /// Enumeration for MaskingMode of image.
245 [EditorBrowsable(EditorBrowsableState.Never)]
246 public enum MaskingModeType
249 /// Applies alpha masking on rendering time.
251 [EditorBrowsable(EditorBrowsableState.Never)]
254 /// Applies alpha masking on loading time.
256 [EditorBrowsable(EditorBrowsableState.Never)]
261 /// ImageView ResourceUrl, type string.
262 /// This is one of mandatory property. Even if not set or null set, it sets empty string ("") internally.
263 /// When it is set as null, it gives empty string ("") to be read.
265 /// <since_tizen> 3 </since_tizen>
266 public string ResourceUrl
270 return (string)GetValue(ResourceUrlProperty);
274 SetValue(ResourceUrlProperty, value);
275 NotifyPropertyChanged();
280 /// This will be deprecated, Use Image instead. <br />
281 /// ImageView ImageMap, type PropertyMap: string if it is a URL, map otherwise.
283 /// <since_tizen> 3 </since_tizen>
284 [Obsolete("Do not use this, that will be deprecated. Use Image property instead.")]
285 [EditorBrowsable(EditorBrowsableState.Never)]
286 public PropertyMap ImageMap
290 return GetValue(ImageMapProperty) as PropertyMap;
294 SetValue(ImageMapProperty, value);
295 NotifyPropertyChanged();
298 private PropertyMap InternalImageMap
304 // Sync as current properties
307 // Get current properties force.
308 PropertyMap returnValue = new PropertyMap();
309 PropertyValue image = GetProperty(ImageView.Property.IMAGE);
310 image?.Get(returnValue);
313 // Update cached property map
314 if(returnValue != null)
316 MergeCachedImageVisualProperty(returnValue);
329 PropertyValue setValue = new Tizen.NUI.PropertyValue(value);
330 SetProperty(ImageView.Property.IMAGE, setValue);
332 // Image properties are changed hardly. We should ignore lazy UpdateImage
333 imagePropertyUpdatedFlag = false;
334 cachedImagePropertyMap?.Dispose();
335 cachedImagePropertyMap = null;
336 MergeCachedImageVisualProperty(value);
338 NotifyPropertyChanged();
345 /// ImageView Image, type PropertyMap: string if it is a URL, map otherwise.
348 /// This PropertyMap use a <see cref="ImageVisualProperty"/>. <br />
349 /// See <see cref="ImageVisualProperty"/> for a detailed description. <br />
350 /// you can also use <see cref="Visual.Property"/>. <br />
351 /// See <see cref="Visual.Property"/> for a detailed description. <br />
354 /// The following example demonstrates how to use the Image property.
356 /// PropertyMap map = new PropertyMap();
357 /// map.Insert(Visual.Property.Type, new PropertyValue((int)Visual.Type.Image));
358 /// map.Insert(ImageVisualProperty.AlphaMaskURL, new PropertyValue(url));
359 /// map.Insert(ImageVisualProperty.FittingMode, new PropertyValue((int)FittingModeType.ScaleToFill);
360 /// imageview.Image = map;
363 /// <since_tizen> 4 </since_tizen>
364 public PropertyMap Image
370 return (PropertyMap)GetValue(ImageProperty);
381 SetValue(ImageProperty, value);
382 NotifyPropertyChanged();
388 /// ImageView PreMultipliedAlpha, type Boolean.<br />
389 /// Image must be initialized.<br />
391 /// <since_tizen> 3 </since_tizen>
392 public bool PreMultipliedAlpha
396 #if NUI_PROPERTY_CHANGE_DEBUG
397 PreMultipliedAlphaGetter++;
399 return (bool)GetValue(PreMultipliedAlphaProperty);
403 #if NUI_PROPERTY_CHANGE_DEBUG
404 PreMultipliedAlphaSetter++;
406 SetValue(PreMultipliedAlphaProperty, value);
407 NotifyPropertyChanged();
412 /// ImageView PixelArea, type Vector4 (Animatable property).<br />
413 /// Pixel area is a relative value with the whole image area as [0.0, 0.0, 1.0, 1.0].<br />
416 /// The property cascade chaining set is possible. For example, this (imageView.PixelArea.X = 0.1f;) is possible.
418 /// <since_tizen> 3 </since_tizen>
419 public RelativeVector4 PixelArea
423 #if NUI_PROPERTY_CHANGE_DEBUG
427 #if NUI_PROPERTY_CHANGE_2
428 return (RelativeVector4)GetValue(PixelAreaProperty);
430 RelativeVector4 temp = (RelativeVector4)GetValue(PixelAreaProperty);
431 return new RelativeVector4(OnPixelAreaChanged, temp.X, temp.Y, temp.Z, temp.W);
436 #if NUI_PROPERTY_CHANGE_DEBUG
439 SetValue(PixelAreaProperty, value);
440 NotifyPropertyChanged();
445 /// The border of the image in the order: left, right, bottom, top.<br />
446 /// If set, ImageMap will be ignored.<br />
447 /// For N-Patch images only.<br />
451 /// The property cascade chaining set is possible. For example, this (imageView.Border.X = 1;) is possible.
453 /// <since_tizen> 3 </since_tizen>
454 public Rectangle Border
458 Rectangle temp = (Rectangle)GetValue(BorderProperty);
465 return new Rectangle(OnBorderChanged, temp.X, temp.Y, temp.Width, temp.Height);
470 SetValue(BorderProperty, value);
471 NotifyPropertyChanged();
476 /// Gets or sets whether to draw the borders only (if true).<br />
477 /// If not specified, the default is false.<br />
478 /// For N-Patch images only.<br />
481 /// <since_tizen> 3 </since_tizen>
482 public bool BorderOnly
486 return (bool)GetValue(BorderOnlyProperty);
490 SetValue(BorderOnlyProperty, value);
491 NotifyPropertyChanged();
496 /// Gets or sets whether to synchronous loading the resourceurl of image.<br />
498 /// <since_tizen> 3 </since_tizen>
499 [Obsolete("This has been deprecated since API9 and will be removed in API11. Use SynchronousLoading instead.")]
500 public bool SynchronosLoading
504 return SynchronousLoading;
508 SynchronousLoading = value;
513 /// Gets or sets whether the image of the ResourceUrl property will be loaded synchronously.<br />
516 /// Changing this property make this ImageView load image synchronously at the next loading
517 /// by following operation: <see cref="Reload"/>, <see cref="SetImage(string)"/>,
518 /// and by some properties those cause reloading: <see cref="ResourceUrl"/>, <see cref="PreMultipliedAlpha"/> and etc.
520 /// <since_tizen> 9 </since_tizen>
521 public bool SynchronousLoading
525 return (bool)GetValue(SynchronousLoadingProperty);
529 SetValue(SynchronousLoadingProperty, value);
530 NotifyPropertyChanged();
535 /// Gets or sets whether to automatically correct the orientation of an image.<br />
537 /// <since_tizen> 5 </since_tizen>
538 public bool OrientationCorrection
542 return (bool)GetValue(OrientationCorrectionProperty);
546 SetValue(OrientationCorrectionProperty, value);
547 NotifyPropertyChanged();
552 /// Gets or sets whether to apply mask on GPU or not.<br />
554 [EditorBrowsable(EditorBrowsableState.Never)]
555 public MaskingModeType MaskingMode
559 return (MaskingModeType)GetValue(MaskingModeProperty);
563 SetValue(MaskingModeProperty, value);
564 NotifyPropertyChanged();
568 private MaskingModeType InternalMaskingMode
572 int ret = (int)MaskingModeType.MaskingOnLoading;
574 PropertyValue maskingMode = GetCachedImageVisualProperty(ImageVisualProperty.MaskingMode);
575 maskingMode?.Get(out ret);
576 maskingMode?.Dispose();
578 return (MaskingModeType)ret;
582 MaskingModeType ret = value;
583 PropertyValue setValue = new PropertyValue((int)ret);
584 UpdateImage(ImageVisualProperty.MaskingMode, setValue);
590 /// Gets the loading state of the visual resource.
592 /// <since_tizen> 5 </since_tizen>
593 public ImageView.LoadingStatusType LoadingStatus
597 return (ImageView.LoadingStatusType)Interop.View.GetVisualResourceStatus(SwigCPtr, (int)Property.IMAGE);
602 /// Downcasts a handle to imageView handle.
604 /// <exception cref="ArgumentNullException"> Thrown when handle is null. </exception>
605 /// Do not use this, that will be deprecated. Use as keyword instead.
606 /// <since_tizen> 3 </since_tizen>
607 [Obsolete("Do not use this, that will be deprecated. Use as keyword instead. " +
609 "BaseHandle handle = new ImageView(imagePath); " +
610 "ImageView image = handle as ImageView")]
611 [EditorBrowsable(EditorBrowsableState.Never)]
612 public static ImageView DownCast(BaseHandle handle)
616 throw new ArgumentNullException(nameof(handle));
618 ImageView ret = Registry.GetManagedBaseHandleFromNativePtr(handle) as ImageView;
619 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
624 /// Sets this ImageView from the given URL.<br />
625 /// If the URL is empty, ImageView will not display anything.<br />
627 /// <param name="url">The URL to the image resource to display.</param>
628 /// <exception cref="ArgumentNullException"> Thrown when url is null. </exception>
629 /// <since_tizen> 3 </since_tizen>
630 public void SetImage(string url)
634 throw new ArgumentNullException(nameof(url));
637 if (url.Contains(".json"))
639 Tizen.Log.Fatal("NUI", "[ERROR] Do not set lottie file in ImageView! This is temporary checking, will be removed soon!");
643 Interop.ImageView.SetImage(SwigCPtr, url);
644 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
650 /// Queries if all resources required by a control are loaded and ready.<br />
651 /// Most resources are only loaded when the control is placed on the stage.<br />
652 /// True if the resources are loaded and ready, false otherwise.<br />
654 /// <since_tizen> 3 </since_tizen>
655 public new bool IsResourceReady()
657 bool ret = Interop.View.IsResourceReady(SwigCPtr);
658 if (NDalicPINVOKE.SWIGPendingException.Pending)
659 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
664 /// Forcefully reloads the image. All the visuals using this image will reload to the latest image.
666 /// <since_tizen> 5 </since_tizen>
669 // Sync as current properties
672 #if NUI_VISUAL_PROPERTY_CHANGE_1
673 Interop.View.DoActionWithEmptyAttributes(this.SwigCPtr, ImageView.Property.IMAGE, ActionReload);
675 PropertyValue attributes = new PropertyValue(0);
676 this.DoAction(ImageView.Property.IMAGE, ActionReload, attributes);
677 attributes?.Dispose();
682 /// Plays the animated GIF. This is also the default playback mode.
684 /// <since_tizen> 5 </since_tizen>
687 // Sync as current properties
690 #if NUI_VISUAL_PROPERTY_CHANGE_1
691 Interop.View.DoActionWithEmptyAttributes(this.SwigCPtr, ImageView.Property.IMAGE, ActionPlay);
693 PropertyValue attributes = new PropertyValue(0);
694 this.DoAction(ImageView.Property.IMAGE, ActionPlay, attributes);
695 attributes?.Dispose();
700 /// Pauses the animated GIF.
702 /// <since_tizen> 5 </since_tizen>
705 // Sync as current properties
708 #if NUI_VISUAL_PROPERTY_CHANGE_1
709 Interop.View.DoActionWithEmptyAttributes(this.SwigCPtr, ImageView.Property.IMAGE, ActionPause);
711 PropertyValue attributes = new PropertyValue(0);
712 this.DoAction(ImageView.Property.IMAGE, ActionPause, attributes);
713 attributes?.Dispose();
718 /// Stops the animated GIF.
720 /// <since_tizen> 5 </since_tizen>
723 // Sync as current properties
727 #if NUI_VISUAL_PROPERTY_CHANGE_1
728 Interop.View.DoActionWithEmptyAttributes(this.SwigCPtr, ImageView.Property.IMAGE, ActionStop);
730 PropertyValue attributes = new PropertyValue(0);
731 this.DoAction(ImageView.Property.IMAGE, ActionStop, attributes);
732 attributes?.Dispose();
737 /// Gets or sets the URL of the alpha mask.<br />
740 /// <since_tizen> 6</since_tizen>
741 [EditorBrowsable(EditorBrowsableState.Never)]
742 public string AlphaMaskURL
746 return GetValue(AlphaMaskURLProperty) as string;
750 SetValue(AlphaMaskURLProperty, value);
751 NotifyPropertyChanged();
755 private string InternalAlphaMaskURL
761 PropertyValue maskUrl = GetCachedImageVisualProperty(ImageVisualProperty.AlphaMaskURL);
762 maskUrl?.Get(out ret);
769 PropertyValue setValue = new PropertyValue(value ?? "");
770 UpdateImage(ImageVisualProperty.AlphaMaskURL, setValue);
771 // When we never set CropToMask property before, we should set default value as true.
772 using(PropertyValue cropToMask = GetCachedImageVisualProperty(ImageVisualProperty.CropToMask))
774 if(cropToMask == null)
776 using PropertyValue setCropValue = new PropertyValue(true);
777 UpdateImage(ImageVisualProperty.CropToMask, setCropValue);
786 /// Whether to crop image to mask or scale mask to fit image.
788 /// <since_tizen> 6 </since_tizen>
789 public bool CropToMask
793 return (bool)GetValue(CropToMaskProperty);
797 SetValue(CropToMaskProperty, value);
798 NotifyPropertyChanged();
801 private bool InternalCropToMask
807 PropertyValue cropToMask = GetCachedImageVisualProperty(ImageVisualProperty.CropToMask);
808 cropToMask?.Get(out ret);
809 cropToMask?.Dispose();
815 PropertyValue setValue = new PropertyValue(value);
816 UpdateImage(ImageVisualProperty.CropToMask, setValue);
822 /// Actions property value for Reload image.
824 private int ActionReload { get; set; } = Interop.ImageView.ImageVisualActionReloadGet();
827 /// Actions property value to Play animated images.
828 /// This property can be redefined by child class if it use different value.
830 [EditorBrowsable(EditorBrowsableState.Never)]
831 protected int ActionPlay { get; set; } = Interop.AnimatedImageView.AnimatedImageVisualActionPlayGet();
834 /// Actions property value to Pause animated images.
835 /// This property can be redefined by child class if it use different value.
837 [EditorBrowsable(EditorBrowsableState.Never)]
838 protected int ActionPause { get; set; } = Interop.AnimatedImageView.AnimatedImageVisualActionPauseGet();
841 /// Actions property value to Stop animated images.
842 /// This property can be redefined by child class if it use different value.
844 [EditorBrowsable(EditorBrowsableState.Never)]
845 protected int ActionStop { get; set; } = Interop.AnimatedImageView.AnimatedImageVisualActionStopGet();
847 internal VisualFittingModeType ConvertFittingModetoVisualFittingMode(FittingModeType value)
851 case FittingModeType.ShrinkToFit:
852 return VisualFittingModeType.FitKeepAspectRatio;
853 case FittingModeType.ScaleToFill:
854 return VisualFittingModeType.OverFitKeepAspectRatio;
855 case FittingModeType.Center:
856 return VisualFittingModeType.Center;
857 case FittingModeType.Fill:
858 return VisualFittingModeType.Fill;
859 case FittingModeType.FitHeight:
860 return VisualFittingModeType.FitHeight;
861 case FittingModeType.FitWidth:
862 return VisualFittingModeType.FitWidth;
864 return VisualFittingModeType.Fill;
868 internal FittingModeType ConvertVisualFittingModetoFittingMode(VisualFittingModeType value)
872 case VisualFittingModeType.FitKeepAspectRatio:
873 return FittingModeType.ShrinkToFit;
874 case VisualFittingModeType.OverFitKeepAspectRatio:
875 return FittingModeType.ScaleToFill;
876 case VisualFittingModeType.Center:
877 return FittingModeType.Center;
878 case VisualFittingModeType.Fill:
879 return FittingModeType.Fill;
880 case VisualFittingModeType.FitHeight:
881 return FittingModeType.FitHeight;
882 case VisualFittingModeType.FitWidth:
883 return FittingModeType.FitWidth;
885 return FittingModeType.ShrinkToFit;
889 internal override LayoutItem CreateDefaultLayout()
891 return new ImageLayout();
895 /// Gets or sets fitting options used when resizing images to fit.<br />
896 /// If not supplied, the default is FittingModeType.Fill.<br />
897 /// For normal quad images only.<br />
900 /// <since_tizen> 6 </since_tizen>
901 [EditorBrowsable(EditorBrowsableState.Never)]
902 public FittingModeType FittingMode
906 return (FittingModeType)GetValue(FittingModeProperty);
910 SetValue(FittingModeProperty, value);
911 NotifyPropertyChanged();
915 private FittingModeType InternalFittingMode
919 int ret = (int)VisualFittingModeType.Fill;
921 PropertyValue fittingMode = GetCachedImageVisualProperty(Visual.Property.VisualFittingMode);
922 fittingMode?.Get(out ret);
923 fittingMode?.Dispose();
925 return ConvertVisualFittingModetoFittingMode((VisualFittingModeType)ret);
929 VisualFittingModeType ret = ConvertFittingModetoVisualFittingMode(value);
930 PropertyValue setValue = new PropertyValue((int)ret);
931 UpdateImage(Visual.Property.VisualFittingMode, setValue);
937 /// Gets or sets the desired image width.<br />
938 /// If not specified, the actual image width is used.<br />
939 /// For normal quad images only.<br />
942 /// <since_tizen> 6 </since_tizen>
943 [EditorBrowsable(EditorBrowsableState.Never)]
944 public int DesiredWidth
948 return (int)GetValue(DesiredWidthProperty);
952 SetValue(DesiredWidthProperty, value);
953 NotifyPropertyChanged();
956 private int InternalDesiredWidth
960 // Sync as current properties only if both _desired_width and _desired_height are setuped.
961 if(_desired_width != -1 && _desired_height != -1)
965 PropertyValue desirewidth = GetCachedImageVisualProperty(ImageVisualProperty.DesiredWidth);
966 desirewidth?.Get(out _desired_width);
967 desirewidth?.Dispose();
969 return _desired_width;
973 if (_desired_width != value)
975 _desired_width = value;
976 PropertyValue setValue = new PropertyValue(value);
977 UpdateImage(ImageVisualProperty.DesiredWidth, setValue);
984 /// Gets or sets the desired image height.<br />
985 /// If not specified, the actual image height is used.<br />
986 /// For normal quad images only.<br />
989 /// <since_tizen> 6 </since_tizen>
990 [EditorBrowsable(EditorBrowsableState.Never)]
991 public int DesiredHeight
995 return (int)GetValue(DesiredHeightProperty);
999 SetValue(DesiredHeightProperty, value);
1000 NotifyPropertyChanged();
1003 private int InternalDesiredHeight
1007 // Sync as current properties only if both _desired_width and _desired_height are setuped.
1008 if(_desired_width != -1 && _desired_height != -1)
1012 PropertyValue desireheight = GetCachedImageVisualProperty(ImageVisualProperty.DesiredHeight);
1013 desireheight?.Get(out _desired_height);
1014 desireheight?.Dispose();
1016 return _desired_height;
1020 if (_desired_height != value)
1022 _desired_height = value;
1023 PropertyValue setValue = new PropertyValue(value);
1024 UpdateImage(ImageVisualProperty.DesiredHeight, setValue);
1025 setValue?.Dispose();
1031 /// Gets or sets ReleasePolicy for image.<br />
1032 /// If not supplied, the default is ReleasePolicyType.Detached.<br />
1034 [EditorBrowsable(EditorBrowsableState.Never)]
1035 public ReleasePolicyType ReleasePolicy
1039 return (ReleasePolicyType)GetValue(ReleasePolicyProperty);
1043 SetValue(ReleasePolicyProperty, value);
1044 NotifyPropertyChanged();
1048 private ReleasePolicyType InternalReleasePolicy
1052 int ret = (int)ReleasePolicyType.Detached;
1054 PropertyValue releasePoli = GetCachedImageVisualProperty(ImageVisualProperty.ReleasePolicy);
1055 releasePoli?.Get(out ret);
1056 releasePoli?.Dispose();
1058 return (ReleasePolicyType)ret;
1062 PropertyValue setValue = new PropertyValue((int)value);
1063 UpdateImage(ImageVisualProperty.ReleasePolicy, setValue);
1064 setValue?.Dispose();
1069 /// Gets or sets the wrap mode for the u coordinate.<br />
1070 /// It decides how the texture should be sampled when the u coordinate exceeds the range of 0.0 to 1.0.<br />
1071 /// If not specified, the default is WrapModeType.Default(CLAMP).<br />
1072 /// For normal quad images only.<br />
1075 /// <since_tizen> 6 </since_tizen>
1076 [EditorBrowsable(EditorBrowsableState.Never)]
1077 public WrapModeType WrapModeU
1081 return (WrapModeType)GetValue(WrapModeUProperty);
1085 SetValue(WrapModeUProperty, value);
1086 NotifyPropertyChanged();
1090 private WrapModeType InternalWrapModeU
1094 int ret = (int)WrapModeType.Default;
1096 PropertyValue wrapModeU = GetCachedImageVisualProperty(ImageVisualProperty.WrapModeU);
1097 wrapModeU?.Get(out ret);
1098 wrapModeU?.Dispose();
1100 return (WrapModeType)ret;
1104 PropertyValue setValue = new PropertyValue((int)value);
1105 UpdateImage(ImageVisualProperty.WrapModeU, setValue);
1106 setValue?.Dispose();
1111 /// Gets or sets the wrap mode for the v coordinate.<br />
1112 /// It decides how the texture should be sampled when the v coordinate exceeds the range of 0.0 to 1.0.<br />
1113 /// 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 />
1114 /// If not specified, the default is WrapModeType.Default(CLAMP).<br />
1115 /// For normal quad images only.
1118 /// <since_tizen> 6 </since_tizen>
1119 [EditorBrowsable(EditorBrowsableState.Never)]
1120 public WrapModeType WrapModeV
1124 return (WrapModeType)GetValue(WrapModeVProperty);
1128 SetValue(WrapModeVProperty, value);
1129 NotifyPropertyChanged();
1133 private WrapModeType InternalWrapModeV
1137 int ret = (int)WrapModeType.Default;
1139 PropertyValue wrapModeV = GetCachedImageVisualProperty(ImageVisualProperty.WrapModeV);
1140 wrapModeV?.Get(out ret);
1141 wrapModeV?.Dispose();
1143 return (WrapModeType)ret;
1147 PropertyValue setValue = new PropertyValue((int)value);
1148 UpdateImage(ImageVisualProperty.WrapModeV, setValue);
1149 setValue?.Dispose();
1154 /// Gets or sets the mode to adjust view size to preserve the aspect ratio of the image resource.
1157 /// This is false by default.
1158 /// If this is set to be true, then the width or height value, which is not set by user explicitly, can be changed automatically
1159 /// to preserve the aspect ratio of the image resource.
1160 /// AdjustViewSize works only if ImageView is added to a View having Layout.
1161 /// e.g. If the image resource size is (100, 100), then the ImageView requests size (100, 100) to its parent layout by default.
1162 /// If the ImageView's HeightSpecification is 50 and AdjustViewSize is true, then the ImageView requests size (50, 50) instead of (100, 50).
1164 /// <since_tizen> 9 </since_tizen>
1165 public bool AdjustViewSize
1169 return (bool)GetValue(AdjustViewSizeProperty);
1173 SetValue(AdjustViewSizeProperty, value);
1174 NotifyPropertyChanged();
1177 private bool adjustViewSize = false;
1179 internal Selector<string> ResourceUrlSelector
1181 get => GetSelector<string>(resourceUrlSelector, ImageView.ResourceUrlProperty);
1184 resourceUrlSelector?.Reset(this);
1185 if (value == null) return;
1187 if (value.HasAll()) SetResourceUrl(value.All);
1188 else resourceUrlSelector = new TriggerableSelector<string>(this, value, SetResourceUrl, true);
1193 /// Get attributes, it is abstract function and must be override.
1195 [EditorBrowsable(EditorBrowsableState.Never)]
1196 protected override ViewStyle CreateViewStyle()
1198 return new ImageViewStyle();
1201 internal void SetImage(string url, Uint16Pair size)
1203 if (url.Contains(".json"))
1205 Tizen.Log.Fatal("NUI", "[ERROR] Do not set lottie file in ImageView! This is temporary checking, will be removed soon!");
1209 Interop.ImageView.SetImage(SwigCPtr, url, Uint16Pair.getCPtr(size));
1210 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
1215 internal ViewResourceReadySignal ResourceReadySignal(View view)
1217 ViewResourceReadySignal ret = new ViewResourceReadySignal(Interop.View.ResourceReadySignal(View.getCPtr(view)), false);
1218 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
1222 internal override void ApplyCornerRadius()
1224 base.ApplyCornerRadius();
1226 if (backgroundExtraData == null) return;
1228 #if NUI_VISUAL_PROPERTY_CHANGE_1
1229 // Update corner radius properties to image by ActionUpdateProperty
1230 if (backgroundExtraData.CornerRadius != null)
1232 Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.CornerRadius, Vector4.getCPtr(backgroundExtraData.CornerRadius));
1234 Interop.View.InternalUpdateVisualPropertyInt(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.CornerRadiusPolicy, (int)backgroundExtraData.CornerRadiusPolicy);
1236 // Apply corner radius to IMAGE.
1237 var cornerRadiusValue = backgroundExtraData.CornerRadius == null ? new PropertyValue() : new PropertyValue(backgroundExtraData.CornerRadius);
1238 var cornerRadiusPolicyValue = new PropertyValue((int)backgroundExtraData.CornerRadiusPolicy);
1240 // Make current propertyMap
1241 PropertyMap currentPropertyMap = new PropertyMap();
1242 currentPropertyMap[Visual.Property.CornerRadius] = cornerRadiusValue;
1243 currentPropertyMap[Visual.Property.CornerRadiusPolicy] = cornerRadiusPolicyValue;
1244 var temp = new PropertyValue(currentPropertyMap);
1246 // Update corner radius properties to image by ActionUpdateProperty
1247 this.DoAction(ImageView.Property.IMAGE, ActionUpdateProperty, temp);
1250 currentPropertyMap.Dispose();
1251 cornerRadiusValue.Dispose();
1252 cornerRadiusPolicyValue.Dispose();
1256 internal override void ApplyBorderline()
1258 base.ApplyBorderline();
1260 if (backgroundExtraData == null) return;
1262 #if NUI_VISUAL_PROPERTY_CHANGE_1
1263 // Update borderline properties to image by ActionUpdateProperty
1264 Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineWidth, backgroundExtraData.BorderlineWidth);
1265 Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineColor, Vector4.getCPtr(backgroundExtraData.BorderlineColor ?? Color.Black));
1266 Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineOffset, backgroundExtraData.BorderlineOffset);
1268 // Apply borderline to IMAGE.
1269 var borderlineWidthValue = new PropertyValue(backgroundExtraData.BorderlineWidth);
1270 var borderlineColorValue = backgroundExtraData.BorderlineColor == null ? new PropertyValue(Color.Black) : new PropertyValue(backgroundExtraData.BorderlineColor);
1271 var borderlineOffsetValue = new PropertyValue(backgroundExtraData.BorderlineOffset);
1273 // Make current propertyMap
1274 PropertyMap currentPropertyMap = new PropertyMap();
1275 currentPropertyMap[Visual.Property.BorderlineWidth] = borderlineWidthValue;
1276 currentPropertyMap[Visual.Property.BorderlineColor] = borderlineColorValue;
1277 currentPropertyMap[Visual.Property.BorderlineOffset] = borderlineOffsetValue;
1278 var temp = new PropertyValue(currentPropertyMap);
1280 // Update borderline properties to image by ActionUpdateProperty
1281 this.DoAction(ImageView.Property.IMAGE, ActionUpdateProperty, temp);
1284 currentPropertyMap.Dispose();
1285 borderlineWidthValue.Dispose();
1286 borderlineColorValue.Dispose();
1287 borderlineOffsetValue.Dispose();
1291 internal ResourceLoadingStatusType GetResourceStatus()
1293 return (ResourceLoadingStatusType)Interop.View.GetVisualResourceStatus(this.SwigCPtr, Property.IMAGE);
1297 /// you can override it to clean-up your own resources.
1299 /// <param name="type">DisposeTypes</param>
1300 /// <since_tizen> 3 </since_tizen>
1301 protected override void Dispose(DisposeTypes type)
1308 #if NUI_PROPERTY_CHANGE_2
1309 internalPixelArea?.Dispose();
1312 if (type == DisposeTypes.Explicit)
1315 //Release your own managed resources here.
1316 //You should release all of your own disposable objects here.
1319 borderSelector?.Reset(this);
1320 resourceUrlSelector?.Reset(this);
1321 imagePropertyUpdatedFlag = false;
1322 if (imagePropertyUpdateProcessAttachedFlag)
1324 ProcessorController.Instance.ProcessorOnceEvent -= UpdateImage;
1325 imagePropertyUpdateProcessAttachedFlag = false;
1327 cachedImagePropertyMap?.Dispose();
1328 cachedImagePropertyMap = null;
1334 /// This will not be public opened.
1335 [EditorBrowsable(EditorBrowsableState.Never)]
1336 protected override void ReleaseSwigCPtr(System.Runtime.InteropServices.HandleRef swigCPtr)
1338 Interop.ImageView.DeleteImageView(swigCPtr);
1341 // Callback for View ResourceReady signal
1342 private void OnResourceReady(IntPtr data)
1344 if(!CheckResourceReady())
1349 ResourceReadyEventArgs e = new ResourceReadyEventArgs();
1352 e.View = Registry.GetManagedBaseHandleFromNativePtr(data) as View;
1355 if (_resourceReadyEventHandler != null)
1357 _resourceReadyEventHandler(this, e);
1361 private void SetResourceUrl(string value)
1363 value = (value == null ? "" : value);
1364 if (value.StartsWith("*Resource*"))
1366 string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
1367 value = value.Replace("*Resource*", resource);
1369 if(_resourceUrl != value)
1371 _resourceUrl = value;
1372 if(string.IsNullOrEmpty(_resourceUrl))
1374 // Special case. If we set ResourceUrl as empty, Unregist visual.
1379 using(PropertyValue setValue = new PropertyValue(value))
1381 UpdateImage(ImageVisualProperty.URL, setValue);
1387 private void SetBorder(Rectangle value)
1393 if(_border != value)
1395 _border = new Rectangle(value);
1396 UpdateImage(NpatchImageVisualProperty.Border, new PropertyValue(_border));
1401 /// Unregist image visual directly. After this operation, we cannot get any properties from Image property.
1403 private void RemoveImage()
1405 // If previous resourceUrl was already empty, we don't need to do anything. just ignore.
1406 // Unregist and detach process only if previous resourceUrl was not empty
1407 string currentResourceUrl = "";
1408 PropertyValue currentResourceUrlValue = GetCachedImageVisualProperty(ImageVisualProperty.URL);
1409 if((currentResourceUrlValue?.Get(out currentResourceUrl) ?? false) && !string.IsNullOrEmpty(currentResourceUrl))
1411 PropertyValue emptyValue = new PropertyValue();
1413 // Remove current registed Image.
1414 SetProperty(ImageView.Property.IMAGE, emptyValue);
1416 // Image visual is not exist anymore. We should ignore lazy UpdateImage
1417 imagePropertyUpdatedFlag = false;
1418 if(imagePropertyUpdateProcessAttachedFlag)
1420 ProcessorController.Instance.ProcessorOnceEvent -= UpdateImage;
1421 imagePropertyUpdateProcessAttachedFlag = false;
1423 // Update resourceUrl as empty value
1424 cachedImagePropertyMap[ImageVisualProperty.URL] = emptyValue;
1426 emptyValue?.Dispose();
1428 currentResourceUrlValue?.Dispose();
1432 /// Lazy call to UpdateImage.
1433 /// Collect Properties need to be update, and set properties that starts the Processing.
1435 [EditorBrowsable(EditorBrowsableState.Never)]
1436 protected virtual void UpdateImage(int key, PropertyValue value)
1438 // Update image property map value as inputed value.
1441 if (cachedImagePropertyMap == null)
1443 cachedImagePropertyMap = new PropertyMap();
1446 // To optimization, we don't check URL duplicate case. We already checked before.
1447 if (key != ImageVisualProperty.URL)
1449 using (PropertyValue oldValue = GetCachedImageVisualProperty(key))
1451 if (oldValue != null && oldValue.EqualTo(value))
1453 // Ignore UpdateImage query when we try to update equality value.
1458 imagePropertyUpdatedFlag = true;
1459 cachedImagePropertyMap[key] = value;
1461 // Lazy update only if _resourceUrl is not empty and ProcessAttachedFlag is false.
1462 if (!string.IsNullOrEmpty(_resourceUrl) && !imagePropertyUpdateProcessAttachedFlag)
1464 imagePropertyUpdateProcessAttachedFlag = true;
1465 ProcessorController.Instance.ProcessorOnceEvent += UpdateImage;
1466 // Call process hardly.
1467 ProcessorController.Instance.Awake();
1473 /// Callback function to Lazy UpdateImage.
1475 private void UpdateImage(object source, EventArgs e)
1478 imagePropertyUpdateProcessAttachedFlag = false;
1482 /// Update image-relative properties synchronously.
1483 /// After call this API, All image properties updated.
1486 /// Current version ImageView property update asynchronously.
1487 /// If you want to guarantee that ImageView property setuped,
1488 /// Please call this ImageView.UpdateImage() API.
1490 [EditorBrowsable(EditorBrowsableState.Never)]
1491 protected virtual void UpdateImage()
1493 if(!imagePropertyUpdatedFlag) return;
1495 imagePropertyUpdatedFlag = false;
1497 if(cachedImagePropertyMap == null)
1499 cachedImagePropertyMap = new PropertyMap();
1502 // Checkup the cached visual type is AnimatedImage.
1503 // It is trick to know that this code is running on AnimatedImageView.UpdateImage() or not.
1504 int visualType = -1;
1505 if(!((GetCachedImageVisualProperty(Visual.Property.Type)?.Get(out visualType) ?? false) && visualType == (int)Visual.Type.AnimatedImage))
1507 // If ResourceUrl is not setuped, don't set property. fast return.
1508 if(string.IsNullOrEmpty(_resourceUrl))
1512 if (_border == null)
1514 PropertyValue image = new PropertyValue((int)Visual.Type.Image);
1515 cachedImagePropertyMap[Visual.Property.Type] = image;
1520 PropertyValue nPatch = new PropertyValue((int)Visual.Type.NPatch);
1521 cachedImagePropertyMap[Visual.Property.Type] = nPatch;
1523 PropertyValue border = new PropertyValue(_border);
1524 cachedImagePropertyMap[NpatchImageVisualProperty.Border] = border;
1529 if (backgroundExtraData != null && backgroundExtraData.CornerRadius != null)
1531 using (var cornerRadius = new PropertyValue(backgroundExtraData.CornerRadius))
1532 using (var cornerRadiusPolicy = new PropertyValue((int)backgroundExtraData.CornerRadiusPolicy))
1534 cachedImagePropertyMap[Visual.Property.CornerRadius] = cornerRadius;
1535 cachedImagePropertyMap[Visual.Property.CornerRadiusPolicy] = new PropertyValue((int)(backgroundExtraData.CornerRadiusPolicy));
1539 if (backgroundExtraData != null && backgroundExtraData.BorderlineWidth > 0.0f)
1541 using (var borderlineWidth = new PropertyValue(backgroundExtraData.BorderlineWidth))
1542 using (var borderlineColor = new PropertyValue(backgroundExtraData.BorderlineColor))
1543 using (var borderlineOffset = new PropertyValue(backgroundExtraData.BorderlineOffset))
1545 cachedImagePropertyMap[Visual.Property.BorderlineWidth] = borderlineWidth;
1546 cachedImagePropertyMap[Visual.Property.BorderlineColor] = borderlineColor;
1547 cachedImagePropertyMap[Visual.Property.BorderlineOffset] = borderlineOffset;
1551 // Do Fitting Buffer when desired dimension is set
1552 if (_desired_width != -1 && _desired_height != -1)
1554 if (_resourceUrl != null)
1556 Size2D imageSize = ImageLoader.GetOriginalImageSize(_resourceUrl, true);
1557 if( imageSize.Height > 0 && imageSize.Width > 0 && _desired_width > 0 && _desired_height > 0 )
1559 int adjustedDesiredWidth, adjustedDesiredHeight;
1560 float aspectOfDesiredSize = (float)_desired_height / (float)_desired_width;
1561 float aspectOfImageSize = (float)imageSize.Height / (float)imageSize.Width;
1562 if (aspectOfImageSize > aspectOfDesiredSize)
1564 adjustedDesiredWidth = _desired_width;
1565 adjustedDesiredHeight = imageSize.Height * _desired_width / imageSize.Width;
1569 adjustedDesiredWidth = imageSize.Width * _desired_height / imageSize.Height;
1570 adjustedDesiredHeight = _desired_height;
1573 PropertyValue returnWidth = new PropertyValue(adjustedDesiredWidth);
1574 cachedImagePropertyMap[ImageVisualProperty.DesiredWidth] = returnWidth;
1575 returnWidth?.Dispose();
1576 PropertyValue returnHeight = new PropertyValue(adjustedDesiredHeight);
1577 cachedImagePropertyMap[ImageVisualProperty.DesiredHeight] = returnHeight;
1578 returnHeight?.Dispose();
1579 PropertyValue scaleToFit = new PropertyValue((int)FittingModeType.ScaleToFill);
1580 cachedImagePropertyMap[ImageVisualProperty.FittingMode] = scaleToFit;
1581 scaleToFit?.Dispose();
1585 Tizen.Log.Fatal("NUI", "[ERROR] Can't use DesiredSize when ImageLoading is failed.");
1587 imageSize?.Dispose();
1595 /// Merge our collected properties, and set IMAGE property internally.
1597 private void UpdateImageMap()
1599 // Note : We can't use ImageView.Image property here. Because That property call UpdateImage internally.
1600 using(PropertyMap imageMap = new PropertyMap())
1602 using(PropertyValue returnValue = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE))
1604 returnValue?.Get(imageMap);
1606 if(cachedImagePropertyMap != null)
1608 imageMap?.Merge(cachedImagePropertyMap);
1610 using(PropertyValue setValue = new PropertyValue(imageMap))
1612 SetProperty(ImageView.Property.IMAGE, setValue);
1615 // Update cached image property.
1616 MergeCachedImageVisualProperty(imageMap);
1621 /// Get image visual property by key.
1622 /// If we found value in local Cached result, return that.
1623 /// Else, get synced native map and return that.
1624 /// If there is no matched value, return null.
1626 [EditorBrowsable(EditorBrowsableState.Never)]
1627 protected virtual PropertyValue GetImageVisualProperty(int key)
1629 PropertyValue ret = GetCachedImageVisualProperty(key);
1632 // If we cannot find result form cached map, Get value from native engine.
1633 ret = Image?.Find(key);
1639 /// Get image visual property from NUI cached image map by key.
1640 /// If there is no matched value, return null.
1642 [EditorBrowsable(EditorBrowsableState.Never)]
1643 protected virtual PropertyValue GetCachedImageVisualProperty(int key)
1645 return cachedImagePropertyMap?.Find(key);
1649 /// Update NUI cached image visual property map by inputed property map.
1652 /// For performance issue, we will collect only "cachedImagePropertyKeyList" hold.
1654 [EditorBrowsable(EditorBrowsableState.Never)]
1655 protected virtual void MergeCachedImageVisualProperty(PropertyMap map)
1657 if(map == null) return;
1658 if(cachedImagePropertyMap == null)
1660 cachedImagePropertyMap = new PropertyMap();
1662 foreach(var key in cachedImagePropertyKeyList)
1664 PropertyValue value = map.Find(key);
1667 // Update-or-Insert new value
1668 cachedImagePropertyMap[key] = value;
1674 /// GetNaturalSize() should be guaranteed that ResourceUrl property setuped.
1675 /// So before get base.GetNaturalSize(), we should synchronous image properties
1677 internal override Vector3 GetNaturalSize()
1679 // Sync as current properties
1681 return base.GetNaturalSize();
1684 [EditorBrowsable(EditorBrowsableState.Never)]
1685 protected override bool CheckResourceReady()
1687 // If we have some properties to be updated, this signal is old thing.
1688 // We need to ignore current signal, and wait next.
1689 return !(imagePropertyUpdateProcessAttachedFlag && imagePropertyUpdatedFlag);
1692 private void OnResourceLoaded(IntPtr view)
1694 if(!CheckResourceReady())
1698 ResourceLoadedEventArgs e = new ResourceLoadedEventArgs();
1699 e.Status = (ResourceLoadingStatusType)Interop.View.GetVisualResourceStatus(this.SwigCPtr, Property.IMAGE);
1701 if (_resourceLoadedEventHandler != null)
1703 _resourceLoadedEventHandler(this, e);
1708 /// Event arguments of resource ready.
1710 /// <since_tizen> 3 </since_tizen>
1711 public class ResourceReadyEventArgs : EventArgs
1716 /// The view whose resource is ready.
1718 /// <since_tizen> 3 </since_tizen>
1732 internal class ResourceLoadedEventArgs : EventArgs
1734 private ResourceLoadingStatusType status = ResourceLoadingStatusType.Invalid;
1735 public ResourceLoadingStatusType Status
1748 internal new class Property
1750 internal static readonly int IMAGE = Interop.ImageView.ImageGet();
1751 internal static readonly int PreMultipliedAlpha = Interop.ImageView.PreMultipliedAlphaGet();
1752 internal static readonly int PixelArea = Interop.ImageView.PixelAreaGet();
1755 private enum ImageType
1758 /// For Normal Image.
1763 /// For normal image, with synchronous loading and orientation correction property
1768 /// For nine-patch image
1773 private void OnBorderChanged(int x, int y, int width, int height)
1775 Border = new Rectangle(x, y, width, height);
1777 private void OnPixelAreaChanged(float x, float y, float z, float w)
1779 PixelArea = new RelativeVector4(x, y, z, w);
1782 private class ImageLayout : LayoutItem
1785 /// Gets or sets the mode to adjust view size to preserve the aspect ratio of the image resource.
1786 /// 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.
1788 [EditorBrowsable(EditorBrowsableState.Never)]
1789 public bool AdjustViewSize
1793 return (Owner as ImageView)?.AdjustViewSize ?? false;
1797 if (Owner is ImageView imageView)
1799 imageView.AdjustViewSize = value;
1805 [EditorBrowsable(EditorBrowsableState.Never)]
1806 protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
1808 // To not change the view size by DALi
1809 Owner.WidthResizePolicy = ResizePolicyType.Fixed;
1810 Owner.HeightResizePolicy = ResizePolicyType.Fixed;
1812 float specWidth = widthMeasureSpec.Size.AsDecimal();
1813 float specHeight = heightMeasureSpec.Size.AsDecimal();
1814 float naturalWidth = Owner.NaturalSize.Width;
1815 float naturalHeight = Owner.NaturalSize.Height;
1816 float minWidth = Owner.MinimumSize.Width;
1817 float maxWidth = Owner.MaximumSize.Width;
1818 float minHeight = Owner.MinimumSize.Height;
1819 float maxHeight = Owner.MaximumSize.Height;
1820 float aspectRatio = (naturalWidth > 0) ? (naturalHeight / naturalWidth) : 0;
1822 // Assume that the new width and height are given from the view's suggested size by default.
1823 float newWidth = Math.Min(Math.Max(naturalWidth, minWidth), (maxWidth < 0 ? Int32.MaxValue : maxWidth));
1824 float newHeight = Math.Min(Math.Max(naturalHeight, minHeight), (maxHeight < 0 ? Int32.MaxValue : maxHeight));
1826 // The width and height measure specs are going to be used to set measured size.
1827 // Mark that the measure specs are changed by default to update measure specs later.
1828 bool widthSpecChanged = true;
1829 bool heightSpecChanged = true;
1831 if (widthMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly)
1833 newWidth = specWidth;
1834 widthSpecChanged = false;
1836 if (heightMeasureSpec.Mode != MeasureSpecification.ModeType.Exactly)
1838 if ((AdjustViewSize) && (aspectRatio > 0))
1840 newHeight = newWidth * aspectRatio;
1845 if (heightMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly)
1847 newHeight = specHeight;
1848 heightSpecChanged = false;
1850 if (widthMeasureSpec.Mode != MeasureSpecification.ModeType.Exactly)
1852 if ((AdjustViewSize) && (aspectRatio > 0))
1854 newWidth = newHeight / aspectRatio;
1859 if (widthSpecChanged)
1861 widthMeasureSpec = new MeasureSpecification(new LayoutLength(newWidth), MeasureSpecification.ModeType.Exactly);
1864 if (heightSpecChanged)
1866 heightMeasureSpec = new MeasureSpecification(new LayoutLength(newHeight), MeasureSpecification.ModeType.Exactly);
1869 MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK;
1870 MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK;
1872 SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(newWidth), widthMeasureSpec, childWidthState),
1873 ResolveSizeAndState(new LayoutLength(newHeight), heightMeasureSpec, childHeightState));