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.Runtime.InteropServices;
19 using System.ComponentModel;
20 using Tizen.NUI.Binding;
22 namespace Tizen.NUI.BaseComponents
26 /// ImageView is a class for displaying an image resource.<br />
27 /// An instance of ImageView can be created using a URL or an image instance.<br />
29 /// <since_tizen> 3 </since_tizen>
30 public partial class ImageView : View
32 static ImageView() { }
34 private EventHandler<ResourceReadyEventArgs> _resourceReadyEventHandler;
35 private ResourceReadyEventCallbackType _resourceReadyEventCallback;
36 private EventHandler<ResourceLoadedEventArgs> _resourceLoadedEventHandler;
37 private _resourceLoadedCallbackType _resourceLoadedCallback;
39 private Rectangle _border;
40 private string _resourceUrl = "";
41 private bool _synchronousLoading = false;
42 private string _alphaMaskUrl = null;
43 private int _desired_width = -1;
44 private int _desired_height = -1;
45 private VisualFittingModeType _fittingMode = VisualFittingModeType.Fill;
46 private TriggerableSelector<string> resourceUrlSelector;
47 private TriggerableSelector<Rectangle> borderSelector;
50 /// Creates an initialized ImageView.
52 /// <since_tizen> 3 </since_tizen>
53 public ImageView() : this(Interop.ImageView.New(), true)
55 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
58 /// This will be public opened in next release of tizen after ACR done. Before ACR, it is used as HiddenAPI (InhouseAPI).
59 [EditorBrowsable(EditorBrowsableState.Never)]
60 public ImageView(ViewStyle viewStyle) : this(Interop.ImageView.New(), true, viewStyle)
65 /// Creates an initialized ImageView with setting the status of shown or hidden.
67 /// <param name="shown">false : Not displayed (hidden), true : displayed (shown)</param>
68 /// This will be public opened in next release of tizen after ACR done. Before ACR, it is used as HiddenAPI (InhouseAPI).
69 [EditorBrowsable(EditorBrowsableState.Never)]
70 public ImageView(bool shown) : this(Interop.ImageView.New(), true)
72 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
77 /// Creates an initialized ImageView from a URL to an image resource.<br />
78 /// If the string is empty, ImageView will not display anything.<br />
80 /// <param name="url">The URL of the image resource to display.</param>
81 /// <since_tizen> 3 </since_tizen>
82 public ImageView(string url) : this(Interop.ImageView.New(url), true)
85 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
90 /// Creates an initialized ImageView from a URL to an image resource with setting shown or hidden.
92 /// <param name="url">The URL of the image resource to display.</param>
93 /// <param name="shown">false : Not displayed (hidden), true : displayed (shown)</param>
94 /// This will be public opened in next release of tizen after ACR done. Before ACR, it is used as HiddenAPI (InhouseAPI).
95 [EditorBrowsable(EditorBrowsableState.Never)]
96 public ImageView(string url, bool shown) : this(Interop.ImageView.New(url), true)
99 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
103 internal ImageView(string url, Uint16Pair size, bool shown = true) : this(Interop.ImageView.New(url, Uint16Pair.getCPtr(size)), true)
106 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
114 internal ImageView(global::System.IntPtr cPtr, bool cMemoryOwn, ViewStyle viewStyle, bool shown = true) : base(cPtr, cMemoryOwn, viewStyle)
122 internal ImageView(global::System.IntPtr cPtr, bool cMemoryOwn, bool shown = true) : base(cPtr, cMemoryOwn, null)
130 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
131 private delegate void ResourceReadyEventCallbackType(IntPtr data);
132 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
133 private delegate void _resourceLoadedCallbackType(IntPtr view);
136 /// An event for ResourceReady signal which can be used to subscribe or unsubscribe the event handler.<br />
137 /// This signal is emitted after all resources required by a control are loaded and ready.<br />
138 /// Most resources are only loaded when the control is placed on the stage.<br />
140 /// <since_tizen> 3 </since_tizen>
141 public event EventHandler<ResourceReadyEventArgs> ResourceReady
145 if (_resourceReadyEventHandler == null)
147 _resourceReadyEventCallback = OnResourceReady;
148 ViewResourceReadySignal resourceReadySignal = ResourceReadySignal(this);
149 resourceReadySignal?.Connect(_resourceReadyEventCallback);
150 resourceReadySignal?.Dispose();
153 _resourceReadyEventHandler += value;
158 _resourceReadyEventHandler -= value;
160 ViewResourceReadySignal resourceReadySignal = ResourceReadySignal(this);
161 if (_resourceReadyEventHandler == null && resourceReadySignal?.Empty() == false)
163 resourceReadySignal?.Disconnect(_resourceReadyEventCallback);
165 resourceReadySignal?.Dispose();
169 internal event EventHandler<ResourceLoadedEventArgs> ResourceLoaded
173 if (_resourceLoadedEventHandler == null)
175 _resourceLoadedCallback = OnResourceLoaded;
176 ViewResourceReadySignal resourceReadySignal = this.ResourceReadySignal(this);
177 resourceReadySignal?.Connect(_resourceLoadedCallback);
178 resourceReadySignal?.Dispose();
181 _resourceLoadedEventHandler += value;
185 _resourceLoadedEventHandler -= value;
186 ViewResourceReadySignal resourceReadySignal = this.ResourceReadySignal(this);
187 if (_resourceLoadedEventHandler == null && resourceReadySignal?.Empty() == false)
189 resourceReadySignal?.Disconnect(_resourceLoadedCallback);
191 resourceReadySignal?.Dispose();
196 /// Enumeration for LoadingStatus of image.
198 /// <since_tizen> 5 </since_tizen>
199 public enum LoadingStatusType
202 /// Loading preparing status.
204 /// <since_tizen> 5 </since_tizen>
207 /// Loading ready status.
209 /// <since_tizen> 5 </since_tizen>
212 /// Loading failed status.
214 /// <since_tizen> 5 </since_tizen>
219 /// ImageView ResourceUrl, type string.
220 /// This is one of mandatory property. Even if not set or null set, it sets empty string ("") internally.
221 /// When it is set as null, it gives empty string ("") to be read.
223 /// <since_tizen> 3 </since_tizen>
224 public string ResourceUrl
228 return (string)GetValue(ResourceUrlProperty);
232 SetValue(ResourceUrlProperty, value);
233 NotifyPropertyChanged();
238 /// This will be deprecated, please use Image instead. <br />
239 /// ImageView ImageMap, type PropertyMap: string if it is a URL, map otherwise.
241 /// <since_tizen> 3 </since_tizen>
242 [Obsolete("Please do not use! This will be deprecated! Please use Image property instead!")]
243 [EditorBrowsable(EditorBrowsableState.Never)]
244 public PropertyMap ImageMap
248 return GetValue(ImageMapProperty) as PropertyMap;
252 SetValue(ImageMapProperty, value);
253 NotifyPropertyChanged();
256 private PropertyMap InternalImageMap
262 PropertyMap returnValue = new PropertyMap();
263 PropertyValue image = GetProperty(ImageView.Property.IMAGE);
264 image?.Get(returnValue);
277 PropertyValue setValue = new Tizen.NUI.PropertyValue(value);
278 SetProperty(ImageView.Property.IMAGE, setValue);
279 NotifyPropertyChanged();
286 /// ImageView Image, type PropertyMap: string if it is a URL, map otherwise.
289 /// This PropertyMap use a <see cref="ImageVisualProperty"/>. <br />
290 /// See <see cref="ImageVisualProperty"/> for a detailed description. <br />
291 /// you can also use <see cref="Visual.Property"/>. <br />
292 /// See <see cref="Visual.Property"/> for a detailed description. <br />
295 /// The following example demonstrates how to use the Image property.
297 /// PropertyMap map = new PropertyMap();
298 /// map.Insert(Visual.Property.Type, new PropertyValue((int)Visual.Type.Image));
299 /// map.Insert(ImageVisualProperty.AlphaMaskURL, new PropertyValue(url));
300 /// map.Insert(ImageVisualProperty.FittingMode, new PropertyValue((int)FittingModeType.ScaleToFill);
301 /// imageview.Image = map;
304 /// <since_tizen> 4 </since_tizen>
305 public PropertyMap Image
311 return (PropertyMap)GetValue(ImageProperty);
322 SetValue(ImageProperty, value);
323 NotifyPropertyChanged();
329 /// ImageView PreMultipliedAlpha, type Boolean.<br />
330 /// Image must be initialized.<br />
332 /// <since_tizen> 3 </since_tizen>
333 public bool PreMultipliedAlpha
337 return (bool)GetValue(PreMultipliedAlphaProperty);
341 SetValue(PreMultipliedAlphaProperty, value);
342 NotifyPropertyChanged();
347 /// ImageView PixelArea, type Vector4 (Animatable property).<br />
348 /// Pixel area is a relative value with the whole image area as [0.0, 0.0, 1.0, 1.0].<br />
351 /// The property cascade chaining set is possible. For example, this (imageView.PixelArea.X = 0.1f;) is possible.
353 /// <since_tizen> 3 </since_tizen>
354 public RelativeVector4 PixelArea
358 RelativeVector4 temp = (RelativeVector4)GetValue(PixelAreaProperty);
359 return new RelativeVector4(OnPixelAreaChanged, temp.X, temp.Y, temp.Z, temp.W);
363 SetValue(PixelAreaProperty, value);
364 NotifyPropertyChanged();
369 /// The border of the image in the order: left, right, bottom, top.<br />
370 /// If set, ImageMap will be ignored.<br />
371 /// For N-Patch images only.<br />
375 /// The property cascade chaining set is possible. For example, this (imageView.Border.X = 1;) is possible.
377 /// <since_tizen> 3 </since_tizen>
378 public Rectangle Border
382 Rectangle temp = (Rectangle)GetValue(BorderProperty);
389 return new Rectangle(OnBorderChanged, temp.X, temp.Y, temp.Width, temp.Height);
394 SetValue(BorderProperty, value);
395 NotifyPropertyChanged();
400 /// Gets or sets whether to draw the borders only (if true).<br />
401 /// If not specified, the default is false.<br />
402 /// For N-Patch images only.<br />
405 /// <since_tizen> 3 </since_tizen>
406 public bool BorderOnly
410 return (bool)GetValue(BorderOnlyProperty);
414 SetValue(BorderOnlyProperty, value);
415 NotifyPropertyChanged();
420 /// Gets or sets whether to synchronous loading the resourceurl of image.<br />
422 /// <since_tizen> 3 </since_tizen>
423 [Obsolete("Deprecated since API level 9 and will be removed in API level 11. Please use SynchronousLoading instead!")]
424 public bool SynchronosLoading
428 return SynchronousLoading;
432 SynchronousLoading = value;
437 /// Gets or sets whether the image of the ResourceUrl property will be loaded synchronously.<br />
440 /// Changing this property make this ImageView load image synchronously at the next loading
441 /// by following operation: <see cref="Reload"/>, <see cref="SetImage"/>,
442 /// and by some properties those cause reloading: <see cref="ResourceUrl"/>, <see cref="PreMultipliedAlpha"/> and etc.
444 /// <since_tizen> 9 </since_tizen>
445 public bool SynchronousLoading
449 return (bool)GetValue(SynchronousLoadingProperty);
453 SetValue(SynchronousLoadingProperty, value);
454 NotifyPropertyChanged();
459 /// Gets or sets whether to automatically correct the orientation of an image.<br />
461 /// <since_tizen> 5 </since_tizen>
462 public bool OrientationCorrection
466 return (bool)GetValue(OrientationCorrectionProperty);
470 SetValue(OrientationCorrectionProperty, value);
471 NotifyPropertyChanged();
476 /// Gets the loading state of the visual resource.
478 /// <since_tizen> 5 </since_tizen>
479 public ImageView.LoadingStatusType LoadingStatus
483 return (ImageView.LoadingStatusType)Interop.View.GetVisualResourceStatus(SwigCPtr, (int)Property.IMAGE);
488 /// Downcasts a handle to imageView handle.
490 /// <exception cref="ArgumentNullException"> Thrown when handle is null. </exception>
491 /// Please do not use! this will be deprecated!
492 /// Instead please use as keyword.
493 /// <since_tizen> 3 </since_tizen>
494 [Obsolete("Please do not use! This will be deprecated! Please use as keyword instead! " +
496 "BaseHandle handle = new ImageView(imagePath); " +
497 "ImageView image = handle as ImageView")]
498 [EditorBrowsable(EditorBrowsableState.Never)]
499 public static ImageView DownCast(BaseHandle handle)
503 throw new ArgumentNullException(nameof(handle));
505 ImageView ret = Registry.GetManagedBaseHandleFromNativePtr(handle) as ImageView;
506 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
511 /// Sets this ImageView from the given URL.<br />
512 /// If the URL is empty, ImageView will not display anything.<br />
514 /// <param name="url">The URL to the image resource to display.</param>
515 /// <exception cref="ArgumentNullException"> Thrown when url is null. </exception>
516 /// <since_tizen> 3 </since_tizen>
517 public void SetImage(string url)
521 throw new ArgumentNullException(nameof(url));
524 if (url.Contains(".json"))
526 Tizen.Log.Fatal("NUI", "[ERROR] Please DO NOT set lottie file in ImageView! This is temporary checking, will be removed soon!");
530 Interop.ImageView.SetImage(SwigCPtr, url);
531 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
537 /// Queries if all resources required by a control are loaded and ready.<br />
538 /// Most resources are only loaded when the control is placed on the stage.<br />
539 /// True if the resources are loaded and ready, false otherwise.<br />
541 /// <since_tizen> 3 </since_tizen>
542 public new bool IsResourceReady()
544 bool ret = Interop.View.IsResourceReady(SwigCPtr);
545 if (NDalicPINVOKE.SWIGPendingException.Pending)
546 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
551 /// Forcefully reloads the image. All the visuals using this image will reload to the latest image.
553 /// <since_tizen> 5 </since_tizen>
556 PropertyValue attributes = new PropertyValue(0);
557 this.DoAction(ImageView.Property.IMAGE, Property.ActionReload, attributes);
558 attributes?.Dispose();
562 /// Plays the animated GIF. This is also the default playback mode.
564 /// <since_tizen> 5 </since_tizen>
567 PropertyValue attributes = new PropertyValue(0);
568 this.DoAction(ImageView.Property.IMAGE, Property.ActionPlay, attributes);
569 attributes?.Dispose();
573 /// Pauses the animated GIF.
575 /// <since_tizen> 5 </since_tizen>
578 PropertyValue attributes = new PropertyValue(0);
579 this.DoAction(ImageView.Property.IMAGE, Property.ActionPause, attributes);
580 attributes?.Dispose();
584 /// Stops the animated GIF.
586 /// <since_tizen> 5 </since_tizen>
589 PropertyValue attributes = new PropertyValue(0);
590 this.DoAction(ImageView.Property.IMAGE, Property.ActionStop, attributes);
591 attributes?.Dispose();
595 /// Gets or sets the URL of the alpha mask.<br />
598 /// <since_tizen> 6</since_tizen>
599 [EditorBrowsable(EditorBrowsableState.Never)]
600 public string AlphaMaskURL
604 return GetValue(AlphaMaskURLProperty) as string;
608 SetValue(AlphaMaskURLProperty, value);
609 NotifyPropertyChanged();
613 private string InternalAlphaMaskURL
618 PropertyMap imageMap = new PropertyMap();
619 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
620 image?.Get(imageMap);
621 PropertyValue maskUrl = imageMap?.Find(ImageVisualProperty.AlphaMaskURL);
622 maskUrl?.Get(out ret);
638 _alphaMaskUrl = value;
640 PropertyValue setValue = new PropertyValue(value);
641 UpdateImage(ImageVisualProperty.AlphaMaskURL, setValue);
648 /// Whether to crop image to mask or scale mask to fit image.
650 /// <since_tizen> 6 </since_tizen>
651 public bool CropToMask
655 return (bool)GetValue(CropToMaskProperty);
659 SetValue(CropToMaskProperty, value);
660 NotifyPropertyChanged();
663 private bool InternalCropToMask
668 PropertyMap imageMap = new PropertyMap();
669 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
670 image?.Get(imageMap);
671 PropertyValue cropUrl = imageMap?.Find(ImageVisualProperty.CropToMask);
672 cropUrl?.Get(out ret);
682 PropertyValue setValue = new PropertyValue(value);
683 UpdateImage(ImageVisualProperty.CropToMask, setValue);
688 internal VisualFittingModeType CovertFittingModetoVisualFittingMode(FittingModeType value)
692 case FittingModeType.ShrinkToFit:
693 return VisualFittingModeType.FitKeepAspectRatio;
694 case FittingModeType.ScaleToFill:
695 return VisualFittingModeType.OverFitKeepAspectRatio;
696 case FittingModeType.Center:
697 return VisualFittingModeType.Center;
698 case FittingModeType.Fill:
699 return VisualFittingModeType.Fill;
700 case FittingModeType.FitHeight:
701 return VisualFittingModeType.FitHeight;
702 case FittingModeType.FitWidth:
703 return VisualFittingModeType.FitHeight;
705 return VisualFittingModeType.Fill;
709 internal FittingModeType ConvertVisualFittingModetoFittingMode(VisualFittingModeType value)
713 case VisualFittingModeType.FitKeepAspectRatio:
714 return FittingModeType.ShrinkToFit;
715 case VisualFittingModeType.OverFitKeepAspectRatio:
716 return FittingModeType.ScaleToFill;
717 case VisualFittingModeType.Center:
718 return FittingModeType.Center;
719 case VisualFittingModeType.Fill:
720 return FittingModeType.Fill;
721 case VisualFittingModeType.FitHeight:
722 return FittingModeType.FitHeight;
723 case VisualFittingModeType.FitWidth:
724 return FittingModeType.FitWidth;
726 return FittingModeType.ShrinkToFit;
730 internal override LayoutItem CreateDefaultLayout()
732 return new ImageLayout();
736 /// Gets or sets fitting options used when resizing images to fit.<br />
737 /// If not supplied, the default is FittingModeType.Fill.<br />
738 /// For normal quad images only.<br />
741 /// <since_tizen> 6 </since_tizen>
742 [EditorBrowsable(EditorBrowsableState.Never)]
743 public FittingModeType FittingMode
747 return (FittingModeType)GetValue(FittingModeProperty);
751 SetValue(FittingModeProperty, value);
752 NotifyPropertyChanged();
756 private FittingModeType InternalFittingMode
760 int ret = (int)_fittingMode;
761 PropertyMap imageMap = new PropertyMap();
762 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
763 image?.Get(imageMap);
764 PropertyValue fittingMode = imageMap?.Find(Visual.Property.VisualFittingMode);
765 fittingMode?.Get(out ret);
766 _fittingMode = (VisualFittingModeType)ret;
770 fittingMode?.Dispose();
772 return ConvertVisualFittingModetoFittingMode((VisualFittingModeType)ret);
776 VisualFittingModeType ret = CovertFittingModetoVisualFittingMode(value);
777 PropertyValue setValue = new PropertyValue((int)ret);
778 if(_fittingMode != ret)
781 UpdateImage(Visual.Property.VisualFittingMode, setValue);
790 /// Gets or sets the desired image width.<br />
791 /// If not specified, the actual image width is used.<br />
792 /// For normal quad images only.<br />
795 /// <since_tizen> 6 </since_tizen>
796 [EditorBrowsable(EditorBrowsableState.Never)]
797 public int DesiredWidth
801 return (int)GetValue(DesiredWidthProperty);
805 SetValue(DesiredWidthProperty, value);
806 NotifyPropertyChanged();
809 private int InternalDesiredWidth
813 PropertyMap imageMap = new PropertyMap();
814 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
815 image?.Get(imageMap);
816 PropertyValue desireWidth = imageMap?.Find(ImageVisualProperty.DesiredWidth);
817 desireWidth?.Get(out _desired_width);
821 desireWidth?.Dispose();
823 return _desired_width;
827 if (_desired_width != value)
829 _desired_width = value;
830 UpdateImage(0, null);
836 /// Gets or sets the desired image height.<br />
837 /// If not specified, the actual image height is used.<br />
838 /// For normal quad images only.<br />
841 /// <since_tizen> 6 </since_tizen>
842 [EditorBrowsable(EditorBrowsableState.Never)]
843 public int DesiredHeight
847 return (int)GetValue(DesiredHeightProperty);
851 SetValue(DesiredHeightProperty, value);
852 NotifyPropertyChanged();
855 private int InternalDesiredHeight
859 PropertyMap imageMap = new PropertyMap();
860 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
861 image?.Get(imageMap);
862 PropertyValue desireheight = imageMap?.Find(ImageVisualProperty.DesiredHeight);
863 desireheight?.Get(out _desired_height);
867 desireheight?.Dispose();
869 return _desired_height;
873 if (_desired_height != value)
875 _desired_height = value;
876 UpdateImage(0, null);
882 /// Gets or sets ReleasePolicy for image.<br />
883 /// If not supplied, the default is ReleasePolicyType.Detached.<br />
885 [EditorBrowsable(EditorBrowsableState.Never)]
886 public ReleasePolicyType ReleasePolicy
890 return (ReleasePolicyType)GetValue(ReleasePolicyProperty);
894 SetValue(ReleasePolicyProperty, value);
895 NotifyPropertyChanged();
899 private ReleasePolicyType InternalReleasePolicy
903 int ret = (int)ReleasePolicyType.Detached;
904 PropertyMap imageMap = new PropertyMap();
905 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
906 image?.Get(imageMap);
907 PropertyValue releasePoli = imageMap?.Find(ImageVisualProperty.ReleasePolicy);
908 releasePoli?.Get(out ret);
912 releasePoli?.Dispose();
914 return (ReleasePolicyType)ret;
918 PropertyValue setValue = new PropertyValue((int)value);
919 UpdateImage(ImageVisualProperty.ReleasePolicy, setValue);
925 /// Gets or sets the wrap mode for the u coordinate.<br />
926 /// It decides how the texture should be sampled when the u coordinate exceeds the range of 0.0 to 1.0.<br />
927 /// If not specified, the default is WrapModeType.Default(CLAMP).<br />
928 /// For normal quad images only.<br />
931 /// <since_tizen> 6 </since_tizen>
932 [EditorBrowsable(EditorBrowsableState.Never)]
933 public WrapModeType WrapModeU
937 return (WrapModeType)GetValue(WrapModeUProperty);
941 SetValue(WrapModeUProperty, value);
942 NotifyPropertyChanged();
946 private WrapModeType InternalWrapModeU
950 int ret = (int)WrapModeType.Default;
951 PropertyMap imageMap = new PropertyMap();
952 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
953 image?.Get(imageMap);
954 PropertyValue warpModeU = imageMap?.Find(ImageVisualProperty.WrapModeU);
955 warpModeU?.Get(out ret);
959 warpModeU?.Dispose();
961 return (WrapModeType)ret;
965 PropertyValue setValue = new PropertyValue((int)value);
966 UpdateImage(ImageVisualProperty.WrapModeU, setValue);
972 /// Gets or sets the wrap mode for the v coordinate.<br />
973 /// It decides how the texture should be sampled when the v coordinate exceeds the range of 0.0 to 1.0.<br />
974 /// 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 />
975 /// If not specified, the default is WrapModeType.Default(CLAMP).<br />
976 /// For normal quad images only.
979 /// <since_tizen> 6 </since_tizen>
980 [EditorBrowsable(EditorBrowsableState.Never)]
981 public WrapModeType WrapModeV
985 return (WrapModeType)GetValue(WrapModeVProperty);
989 SetValue(WrapModeVProperty, value);
990 NotifyPropertyChanged();
994 private WrapModeType InternalWrapModeV
998 int ret = (int)WrapModeType.Default;
999 PropertyMap imageMap = new PropertyMap();
1000 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
1001 image?.Get(imageMap);
1002 PropertyValue wrapModeV = imageMap?.Find(ImageVisualProperty.WrapModeV);
1003 wrapModeV?.Get(out ret);
1005 imageMap?.Dispose();
1007 wrapModeV?.Dispose();
1009 return (WrapModeType)ret;
1013 PropertyValue setValue = new PropertyValue((int)value);
1014 UpdateImage(ImageVisualProperty.WrapModeV, setValue);
1015 setValue?.Dispose();
1020 /// Gets or sets the mode to adjust view size to preserve the aspect ratio of the image resource.
1021 /// 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.
1022 /// AdjustViewSize works only if ImageView is added to a View having Layout.
1024 [EditorBrowsable(EditorBrowsableState.Never)]
1025 public bool AdjustViewSize
1029 return (bool)GetValue(AdjustViewSizeProperty);
1033 SetValue(AdjustViewSizeProperty, value);
1034 NotifyPropertyChanged();
1037 private bool adjustViewSize = false;
1039 internal Selector<string> ResourceUrlSelector
1041 get => GetSelector<string>(resourceUrlSelector, ImageView.ResourceUrlProperty);
1044 resourceUrlSelector?.Reset(this);
1045 if (value == null) return;
1047 if (value.HasAll()) SetResourceUrl(value.All);
1048 else resourceUrlSelector = new TriggerableSelector<string>(this, value, SetResourceUrl, true);
1053 /// Get attributes, it is abstract function and must be override.
1055 [EditorBrowsable(EditorBrowsableState.Never)]
1056 protected override ViewStyle CreateViewStyle()
1058 return new ImageViewStyle();
1061 internal void SetImage(string url, Uint16Pair size)
1063 if (url.Contains(".json"))
1065 Tizen.Log.Fatal("NUI", "[ERROR] Please DO NOT set lottie file in ImageView! This is temporary checking, will be removed soon!");
1069 Interop.ImageView.SetImage(SwigCPtr, url, Uint16Pair.getCPtr(size));
1070 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
1075 internal ViewResourceReadySignal ResourceReadySignal(View view)
1077 ViewResourceReadySignal ret = new ViewResourceReadySignal(Interop.View.ResourceReadySignal(View.getCPtr(view)), false);
1078 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
1082 internal override void ApplyCornerRadius()
1084 base.ApplyCornerRadius();
1086 UpdateImage(0, null);
1089 internal override void ApplyBorderline()
1091 base.ApplyBorderline();
1093 // Apply borderline to IMAGE.
1094 if (backgroundExtraData != null)
1096 var borderlineColor = backgroundExtraData.BorderlineColor == null ? new PropertyValue(Color.Black) : new PropertyValue(backgroundExtraData.BorderlineColor);
1098 // Apply to the image visual
1099 PropertyMap imageMap = new PropertyMap();
1100 PropertyValue imageValue = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
1101 if (imageValue.Get(imageMap) && !imageMap.Empty())
1103 imageMap[Visual.Property.BorderlineWidth] = new PropertyValue(backgroundExtraData.BorderlineWidth);
1104 imageMap[Visual.Property.BorderlineColor] = borderlineColor;
1105 imageMap[Visual.Property.BorderlineOffset] = new PropertyValue(backgroundExtraData.BorderlineOffset);
1106 var temp = new PropertyValue(imageMap);
1107 Tizen.NUI.Object.SetProperty(SwigCPtr, ImageView.Property.IMAGE, temp);
1111 imageValue.Dispose();
1112 borderlineColor.Dispose();
1115 UpdateImage(0, null);
1118 internal ResourceLoadingStatusType GetResourceStatus()
1120 return (ResourceLoadingStatusType)Interop.View.GetVisualResourceStatus(this.SwigCPtr, Property.IMAGE);
1124 /// you can override it to clean-up your own resources.
1126 /// <param name="type">DisposeTypes</param>
1127 /// <since_tizen> 3 </since_tizen>
1128 protected override void Dispose(DisposeTypes type)
1135 if (type == DisposeTypes.Explicit)
1138 //Release your own managed resources here.
1139 //You should release all of your own disposable objects here.
1142 borderSelector?.Reset(this);
1143 resourceUrlSelector?.Reset(this);
1149 /// This will not be public opened.
1150 [EditorBrowsable(EditorBrowsableState.Never)]
1151 protected override void ReleaseSwigCPtr(System.Runtime.InteropServices.HandleRef swigCPtr)
1153 Interop.ImageView.DeleteImageView(swigCPtr);
1156 // Callback for View ResourceReady signal
1157 private void OnResourceReady(IntPtr data)
1159 ResourceReadyEventArgs e = new ResourceReadyEventArgs();
1162 e.View = Registry.GetManagedBaseHandleFromNativePtr(data) as View;
1165 if (_resourceReadyEventHandler != null)
1167 _resourceReadyEventHandler(this, e);
1171 private void SetResourceUrl(string value)
1173 value = (value == null ? "" : value);
1174 if (value.StartsWith("*Resource*"))
1176 string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
1177 value = value.Replace("*Resource*", resource);
1179 _resourceUrl = value;
1180 UpdateImage(ImageVisualProperty.URL, new PropertyValue(value));
1183 private void SetBorder(Rectangle value)
1189 _border = new Rectangle(value);
1190 UpdateImage(NpatchImageVisualProperty.Border, new PropertyValue(_border));
1193 private void UpdateImageMap(PropertyMap fromMap)
1195 PropertyMap imageMap = new PropertyMap();
1197 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
1198 image?.Get(imageMap);
1199 imageMap?.Merge(fromMap);
1200 PropertyValue setValue = new PropertyValue(imageMap);
1201 SetProperty(ImageView.Property.IMAGE, setValue);
1203 imageMap?.Dispose();
1205 setValue?.Dispose();
1208 private void UpdateImage(int key, PropertyValue value)
1210 PropertyMap imageMap = new PropertyMap();
1212 if (_alphaMaskUrl != null)
1214 PropertyValue alphaMaskUrl = new PropertyValue(_alphaMaskUrl);
1215 imageMap?.Insert(ImageVisualProperty.AlphaMaskURL, alphaMaskUrl);
1216 alphaMaskUrl?.Dispose();
1219 if (string.IsNullOrEmpty(_resourceUrl))
1221 PropertyValue resourceUrl = new PropertyValue(_resourceUrl);
1222 imageMap?.Insert(ImageVisualProperty.URL, resourceUrl);
1223 PropertyValue setValue = new PropertyValue(imageMap);
1224 SetProperty(ImageView.Property.IMAGE, setValue);
1225 resourceUrl?.Dispose();
1226 setValue?.Dispose();
1230 if (_border == null)
1232 PropertyValue image = new PropertyValue((int)Visual.Type.Image);
1233 imageMap?.Insert(Visual.Property.Type, image);
1238 PropertyValue nPatch = new PropertyValue((int)Visual.Type.NPatch);
1239 imageMap?.Insert(Visual.Property.Type, nPatch);
1241 PropertyValue border = new PropertyValue(_border);
1242 imageMap?.Insert(NpatchImageVisualProperty.Border, border);
1246 if(key != Visual.Property.VisualFittingMode && _fittingMode != VisualFittingModeType.Fill)
1248 PropertyValue fittingMode = new PropertyValue((int)_fittingMode);
1249 imageMap?.Insert(Visual.Property.VisualFittingMode, fittingMode);
1250 fittingMode?.Dispose();
1253 PropertyValue synchronousLoading = new PropertyValue(_synchronousLoading);
1254 imageMap?.Insert(NpatchImageVisualProperty.SynchronousLoading, synchronousLoading);
1255 synchronousLoading?.Dispose();
1257 if (backgroundExtraData != null && backgroundExtraData.CornerRadius != null)
1259 using (var cornerRadius = new PropertyValue(backgroundExtraData.CornerRadius))
1260 using (var cornerRadiusPolicy = new PropertyValue((int)backgroundExtraData.CornerRadiusPolicy))
1262 imageMap.Insert(Visual.Property.CornerRadius, cornerRadius);
1263 imageMap.Insert(Visual.Property.CornerRadiusPolicy, new PropertyValue((int)(backgroundExtraData.CornerRadiusPolicy)));
1267 if (backgroundExtraData != null && backgroundExtraData.BorderlineWidth > 0.0f)
1269 using (var borderlineWidth = new PropertyValue(backgroundExtraData.BorderlineWidth))
1270 using (var borderlineColor = new PropertyValue(backgroundExtraData.BorderlineColor))
1271 using (var borderlineOffset = new PropertyValue(backgroundExtraData.BorderlineOffset))
1273 imageMap.Insert(Visual.Property.BorderlineWidth, borderlineWidth);
1274 imageMap.Insert(Visual.Property.BorderlineColor, borderlineColor);
1275 imageMap.Insert(Visual.Property.BorderlineOffset, borderlineOffset);
1281 imageMap?.Insert(key, value);
1284 // Do Fitting Buffer when desired dimension is set
1285 if (_desired_width != -1 && _desired_height != -1)
1287 if (_resourceUrl != null)
1289 Size2D imageSize = ImageLoader.GetOriginalImageSize(_resourceUrl, true);
1290 if( imageSize.Height > 0 && imageSize.Width > 0 && _desired_width > 0 && _desired_height > 0 )
1292 int adjustedDesiredWidth, adjustedDesiredHeight;
1293 float aspectOfDesiredSize = (float)_desired_height / (float)_desired_width;
1294 float aspectOfImageSize = (float)imageSize.Height / (float)imageSize.Width;
1295 if (aspectOfImageSize > aspectOfDesiredSize)
1297 adjustedDesiredWidth = _desired_width;
1298 adjustedDesiredHeight = imageSize.Height * _desired_width / imageSize.Width;
1302 adjustedDesiredWidth = imageSize.Width * _desired_height / imageSize.Height;
1303 adjustedDesiredHeight = _desired_height;
1306 PropertyValue returnWidth = new PropertyValue(adjustedDesiredWidth);
1307 imageMap?.Insert(ImageVisualProperty.DesiredWidth, returnWidth);
1308 returnWidth?.Dispose();
1309 PropertyValue returnHeight = new PropertyValue(adjustedDesiredHeight);
1310 imageMap?.Insert(ImageVisualProperty.DesiredHeight, returnHeight);
1311 returnHeight?.Dispose();
1312 PropertyValue scaleToFit = new PropertyValue((int)FittingModeType.ScaleToFill);
1313 imageMap?.Insert(ImageVisualProperty.FittingMode, scaleToFit);
1314 scaleToFit?.Dispose();
1318 Tizen.Log.Fatal("NUI", "[ERROR] Can't use DesiredSize when ImageLoading is failed.");
1320 imageSize?.Dispose();
1324 UpdateImageMap(imageMap);
1326 imageMap?.Dispose();
1331 private void OnResourceLoaded(IntPtr view)
1333 ResourceLoadedEventArgs e = new ResourceLoadedEventArgs();
1334 e.Status = (ResourceLoadingStatusType)Interop.View.GetVisualResourceStatus(this.SwigCPtr, Property.IMAGE);
1336 if (_resourceLoadedEventHandler != null)
1338 _resourceLoadedEventHandler(this, e);
1343 /// Event arguments of resource ready.
1345 /// <since_tizen> 3 </since_tizen>
1346 public class ResourceReadyEventArgs : EventArgs
1351 /// The view whose resource is ready.
1353 /// <since_tizen> 3 </since_tizen>
1367 internal class ResourceLoadedEventArgs : EventArgs
1369 private ResourceLoadingStatusType status = ResourceLoadingStatusType.Invalid;
1370 public ResourceLoadingStatusType Status
1383 internal new class Property
1385 internal static readonly int IMAGE = Interop.ImageView.ImageGet();
1386 internal static readonly int PreMultipliedAlpha = Interop.ImageView.PreMultipliedAlphaGet();
1387 internal static readonly int PixelArea = Interop.ImageView.PixelAreaGet();
1388 internal static readonly int ActionReload = Interop.ImageView.ImageVisualActionReloadGet();
1389 internal static readonly int ActionPlay = Interop.ImageView.ImageVisualActionPlayGet();
1390 internal static readonly int ActionPause = Interop.ImageView.ImageVisualActionPauseGet();
1391 internal static readonly int ActionStop = Interop.ImageView.ImageVisualActionStopGet();
1394 private enum ImageType
1397 /// For Normal Image.
1402 /// For normal image, with synchronous loading and orientation correction property
1407 /// For nine-patch image
1412 private void OnBorderChanged(int x, int y, int width, int height)
1414 Border = new Rectangle(x, y, width, height);
1416 private void OnPixelAreaChanged(float x, float y, float z, float w)
1418 PixelArea = new RelativeVector4(x, y, z, w);
1421 private class ImageLayout : LayoutItem
1424 /// Gets or sets the mode to adjust view size to preserve the aspect ratio of the image resource.
1425 /// 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.
1427 [EditorBrowsable(EditorBrowsableState.Never)]
1428 public bool AdjustViewSize
1432 return (Owner as ImageView)?.AdjustViewSize ?? false;
1436 if (Owner is ImageView imageView)
1438 imageView.AdjustViewSize = value;
1444 [EditorBrowsable(EditorBrowsableState.Never)]
1445 protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
1447 // To not change the view size by DALi
1448 Owner.WidthResizePolicy = ResizePolicyType.Fixed;
1449 Owner.HeightResizePolicy = ResizePolicyType.Fixed;
1451 float specWidth = widthMeasureSpec.Size.AsDecimal();
1452 float specHeight = heightMeasureSpec.Size.AsDecimal();
1453 float naturalWidth = Owner.NaturalSize.Width;
1454 float naturalHeight = Owner.NaturalSize.Height;
1455 float minWidth = Owner.MinimumSize.Width;
1456 float maxWidth = Owner.MaximumSize.Width;
1457 float minHeight = Owner.MinimumSize.Height;
1458 float maxHeight = Owner.MaximumSize.Height;
1459 float aspectRatio = (naturalWidth > 0) ? (naturalHeight / naturalWidth) : 0;
1461 // Assume that the new width and height are given from the view's suggested size by default.
1462 float newWidth = Math.Min(Math.Max(naturalWidth, minWidth), (maxWidth < 0 ? Int32.MaxValue : maxWidth));
1463 float newHeight = Math.Min(Math.Max(naturalHeight, minHeight), (maxHeight < 0 ? Int32.MaxValue : maxHeight));
1465 // The width and height measure specs are going to be used to set measured size.
1466 // Mark that the measure specs are changed by default to update measure specs later.
1467 bool widthSpecChanged = true;
1468 bool heightSpecChanged = true;
1470 if (widthMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly)
1472 newWidth = specWidth;
1473 widthSpecChanged = false;
1475 if (heightMeasureSpec.Mode != MeasureSpecification.ModeType.Exactly)
1477 if ((AdjustViewSize) && (aspectRatio > 0))
1479 newHeight = newWidth * aspectRatio;
1484 if (heightMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly)
1486 newHeight = specHeight;
1487 heightSpecChanged = false;
1489 if (widthMeasureSpec.Mode != MeasureSpecification.ModeType.Exactly)
1491 if ((AdjustViewSize) && (aspectRatio > 0))
1493 newWidth = newHeight / aspectRatio;
1498 if (widthSpecChanged)
1500 widthMeasureSpec = new MeasureSpecification(new LayoutLength(newWidth), MeasureSpecification.ModeType.Exactly);
1503 if (heightSpecChanged)
1505 heightMeasureSpec = new MeasureSpecification(new LayoutLength(newHeight), MeasureSpecification.ModeType.Exactly);
1508 MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK;
1509 MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK;
1511 SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(newWidth), widthMeasureSpec, childWidthState),
1512 ResolveSizeAndState(new LayoutLength(newHeight), heightMeasureSpec, childHeightState));