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(string)"/>,
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, 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, 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, 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, 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);
689 /// Actions property value for Reload image.
691 private int ActionReload { get; set; } = Interop.ImageView.ImageVisualActionReloadGet();
694 /// Actions property value to Play animated images.
695 /// This property can be redefined by child class if it use different value.
697 protected internal int ActionPlay { get; set; } = Interop.AnimatedImageView.AnimatedImageVisualActionPlayGet();
700 /// Actions property value to Pause animated images.
701 /// This property can be redefined by child class if it use different value.
703 protected internal int ActionPause { get; set; } = Interop.AnimatedImageView.AnimatedImageVisualActionPauseGet();
706 /// Actions property value to Stop animated images.
707 /// This property can be redefined by child class if it use different value.
709 protected internal int ActionStop { get; set; } = Interop.AnimatedImageView.AnimatedImageVisualActionStopGet();
711 internal VisualFittingModeType ConvertFittingModetoVisualFittingMode(FittingModeType value)
715 case FittingModeType.ShrinkToFit:
716 return VisualFittingModeType.FitKeepAspectRatio;
717 case FittingModeType.ScaleToFill:
718 return VisualFittingModeType.OverFitKeepAspectRatio;
719 case FittingModeType.Center:
720 return VisualFittingModeType.Center;
721 case FittingModeType.Fill:
722 return VisualFittingModeType.Fill;
723 case FittingModeType.FitHeight:
724 return VisualFittingModeType.FitHeight;
725 case FittingModeType.FitWidth:
726 return VisualFittingModeType.FitWidth;
728 return VisualFittingModeType.Fill;
732 internal FittingModeType ConvertVisualFittingModetoFittingMode(VisualFittingModeType value)
736 case VisualFittingModeType.FitKeepAspectRatio:
737 return FittingModeType.ShrinkToFit;
738 case VisualFittingModeType.OverFitKeepAspectRatio:
739 return FittingModeType.ScaleToFill;
740 case VisualFittingModeType.Center:
741 return FittingModeType.Center;
742 case VisualFittingModeType.Fill:
743 return FittingModeType.Fill;
744 case VisualFittingModeType.FitHeight:
745 return FittingModeType.FitHeight;
746 case VisualFittingModeType.FitWidth:
747 return FittingModeType.FitWidth;
749 return FittingModeType.ShrinkToFit;
753 internal override LayoutItem CreateDefaultLayout()
755 return new ImageLayout();
759 /// Gets or sets fitting options used when resizing images to fit.<br />
760 /// If not supplied, the default is FittingModeType.Fill.<br />
761 /// For normal quad images only.<br />
764 /// <since_tizen> 6 </since_tizen>
765 [EditorBrowsable(EditorBrowsableState.Never)]
766 public FittingModeType FittingMode
770 return (FittingModeType)GetValue(FittingModeProperty);
774 SetValue(FittingModeProperty, value);
775 NotifyPropertyChanged();
779 private FittingModeType InternalFittingMode
783 int ret = (int)_fittingMode;
784 PropertyMap imageMap = new PropertyMap();
785 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
786 image?.Get(imageMap);
787 PropertyValue fittingMode = imageMap?.Find(Visual.Property.VisualFittingMode);
788 fittingMode?.Get(out ret);
789 _fittingMode = (VisualFittingModeType)ret;
793 fittingMode?.Dispose();
795 return ConvertVisualFittingModetoFittingMode((VisualFittingModeType)ret);
799 VisualFittingModeType ret = ConvertFittingModetoVisualFittingMode(value);
800 PropertyValue setValue = new PropertyValue((int)ret);
801 if(_fittingMode != ret)
804 UpdateImage(Visual.Property.VisualFittingMode, setValue);
813 /// Gets or sets the desired image width.<br />
814 /// If not specified, the actual image width is used.<br />
815 /// For normal quad images only.<br />
818 /// <since_tizen> 6 </since_tizen>
819 [EditorBrowsable(EditorBrowsableState.Never)]
820 public int DesiredWidth
824 return (int)GetValue(DesiredWidthProperty);
828 SetValue(DesiredWidthProperty, value);
829 NotifyPropertyChanged();
832 private int InternalDesiredWidth
836 PropertyMap imageMap = new PropertyMap();
837 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
838 image?.Get(imageMap);
839 PropertyValue desireWidth = imageMap?.Find(ImageVisualProperty.DesiredWidth);
840 desireWidth?.Get(out _desired_width);
844 desireWidth?.Dispose();
846 return _desired_width;
850 if (_desired_width != value)
852 _desired_width = value;
853 UpdateImage(0, null);
859 /// Gets or sets the desired image height.<br />
860 /// If not specified, the actual image height is used.<br />
861 /// For normal quad images only.<br />
864 /// <since_tizen> 6 </since_tizen>
865 [EditorBrowsable(EditorBrowsableState.Never)]
866 public int DesiredHeight
870 return (int)GetValue(DesiredHeightProperty);
874 SetValue(DesiredHeightProperty, value);
875 NotifyPropertyChanged();
878 private int InternalDesiredHeight
882 PropertyMap imageMap = new PropertyMap();
883 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
884 image?.Get(imageMap);
885 PropertyValue desireheight = imageMap?.Find(ImageVisualProperty.DesiredHeight);
886 desireheight?.Get(out _desired_height);
890 desireheight?.Dispose();
892 return _desired_height;
896 if (_desired_height != value)
898 _desired_height = value;
899 UpdateImage(0, null);
905 /// Gets or sets ReleasePolicy for image.<br />
906 /// If not supplied, the default is ReleasePolicyType.Detached.<br />
908 [EditorBrowsable(EditorBrowsableState.Never)]
909 public ReleasePolicyType ReleasePolicy
913 return (ReleasePolicyType)GetValue(ReleasePolicyProperty);
917 SetValue(ReleasePolicyProperty, value);
918 NotifyPropertyChanged();
922 private ReleasePolicyType InternalReleasePolicy
926 int ret = (int)ReleasePolicyType.Detached;
927 PropertyMap imageMap = new PropertyMap();
928 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
929 image?.Get(imageMap);
930 PropertyValue releasePoli = imageMap?.Find(ImageVisualProperty.ReleasePolicy);
931 releasePoli?.Get(out ret);
935 releasePoli?.Dispose();
937 return (ReleasePolicyType)ret;
941 PropertyValue setValue = new PropertyValue((int)value);
942 UpdateImage(ImageVisualProperty.ReleasePolicy, setValue);
948 /// Gets or sets the wrap mode for the u coordinate.<br />
949 /// It decides how the texture should be sampled when the u coordinate exceeds the range of 0.0 to 1.0.<br />
950 /// If not specified, the default is WrapModeType.Default(CLAMP).<br />
951 /// For normal quad images only.<br />
954 /// <since_tizen> 6 </since_tizen>
955 [EditorBrowsable(EditorBrowsableState.Never)]
956 public WrapModeType WrapModeU
960 return (WrapModeType)GetValue(WrapModeUProperty);
964 SetValue(WrapModeUProperty, value);
965 NotifyPropertyChanged();
969 private WrapModeType InternalWrapModeU
973 int ret = (int)WrapModeType.Default;
974 PropertyMap imageMap = new PropertyMap();
975 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
976 image?.Get(imageMap);
977 PropertyValue warpModeU = imageMap?.Find(ImageVisualProperty.WrapModeU);
978 warpModeU?.Get(out ret);
982 warpModeU?.Dispose();
984 return (WrapModeType)ret;
988 PropertyValue setValue = new PropertyValue((int)value);
989 UpdateImage(ImageVisualProperty.WrapModeU, setValue);
995 /// Gets or sets the wrap mode for the v coordinate.<br />
996 /// It decides how the texture should be sampled when the v coordinate exceeds the range of 0.0 to 1.0.<br />
997 /// 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 />
998 /// If not specified, the default is WrapModeType.Default(CLAMP).<br />
999 /// For normal quad images only.
1002 /// <since_tizen> 6 </since_tizen>
1003 [EditorBrowsable(EditorBrowsableState.Never)]
1004 public WrapModeType WrapModeV
1008 return (WrapModeType)GetValue(WrapModeVProperty);
1012 SetValue(WrapModeVProperty, value);
1013 NotifyPropertyChanged();
1017 private WrapModeType InternalWrapModeV
1021 int ret = (int)WrapModeType.Default;
1022 PropertyMap imageMap = new PropertyMap();
1023 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
1024 image?.Get(imageMap);
1025 PropertyValue wrapModeV = imageMap?.Find(ImageVisualProperty.WrapModeV);
1026 wrapModeV?.Get(out ret);
1028 imageMap?.Dispose();
1030 wrapModeV?.Dispose();
1032 return (WrapModeType)ret;
1036 PropertyValue setValue = new PropertyValue((int)value);
1037 UpdateImage(ImageVisualProperty.WrapModeV, setValue);
1038 setValue?.Dispose();
1043 /// Gets or sets the mode to adjust view size to preserve the aspect ratio of the image resource.
1046 /// This is false by default.
1047 /// If this is set to be true, then the width or height value, which is not set by user explicitly, can be changed automatically
1048 /// to preserve the aspect ratio of the image resource.
1049 /// AdjustViewSize works only if ImageView is added to a View having Layout.
1050 /// e.g. If the image resource size is (100, 100), then the ImageView requests size (100, 100) to its parent layout by default.
1051 /// If the ImageView's HeightSpecification is 50 and AdjustViewSize is true, then the ImageView requests size (50, 50) instead of (100, 50).
1053 /// <since_tizen> 9 </since_tizen>
1054 public bool AdjustViewSize
1058 return (bool)GetValue(AdjustViewSizeProperty);
1062 SetValue(AdjustViewSizeProperty, value);
1063 NotifyPropertyChanged();
1066 private bool adjustViewSize = false;
1068 internal Selector<string> ResourceUrlSelector
1070 get => GetSelector<string>(resourceUrlSelector, ImageView.ResourceUrlProperty);
1073 resourceUrlSelector?.Reset(this);
1074 if (value == null) return;
1076 if (value.HasAll()) SetResourceUrl(value.All);
1077 else resourceUrlSelector = new TriggerableSelector<string>(this, value, SetResourceUrl, true);
1082 /// Get attributes, it is abstract function and must be override.
1084 [EditorBrowsable(EditorBrowsableState.Never)]
1085 protected override ViewStyle CreateViewStyle()
1087 return new ImageViewStyle();
1090 internal void SetImage(string url, Uint16Pair size)
1092 if (url.Contains(".json"))
1094 Tizen.Log.Fatal("NUI", "[ERROR] Please DO NOT set lottie file in ImageView! This is temporary checking, will be removed soon!");
1098 Interop.ImageView.SetImage(SwigCPtr, url, Uint16Pair.getCPtr(size));
1099 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
1104 internal ViewResourceReadySignal ResourceReadySignal(View view)
1106 ViewResourceReadySignal ret = new ViewResourceReadySignal(Interop.View.ResourceReadySignal(View.getCPtr(view)), false);
1107 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
1111 internal override void ApplyCornerRadius()
1113 base.ApplyCornerRadius();
1115 UpdateImage(0, null);
1118 internal override void ApplyBorderline()
1120 base.ApplyBorderline();
1122 // Apply borderline to IMAGE.
1123 if (backgroundExtraData != null)
1125 var borderlineColor = backgroundExtraData.BorderlineColor == null ? new PropertyValue(Color.Black) : new PropertyValue(backgroundExtraData.BorderlineColor);
1127 // Apply to the image visual
1128 PropertyMap imageMap = new PropertyMap();
1129 PropertyValue imageValue = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
1130 if (imageValue.Get(imageMap) && !imageMap.Empty())
1132 imageMap[Visual.Property.BorderlineWidth] = new PropertyValue(backgroundExtraData.BorderlineWidth);
1133 imageMap[Visual.Property.BorderlineColor] = borderlineColor;
1134 imageMap[Visual.Property.BorderlineOffset] = new PropertyValue(backgroundExtraData.BorderlineOffset);
1135 var temp = new PropertyValue(imageMap);
1136 Tizen.NUI.Object.SetProperty(SwigCPtr, ImageView.Property.IMAGE, temp);
1140 imageValue.Dispose();
1141 borderlineColor.Dispose();
1144 UpdateImage(0, null);
1147 internal ResourceLoadingStatusType GetResourceStatus()
1149 return (ResourceLoadingStatusType)Interop.View.GetVisualResourceStatus(this.SwigCPtr, Property.IMAGE);
1153 /// you can override it to clean-up your own resources.
1155 /// <param name="type">DisposeTypes</param>
1156 /// <since_tizen> 3 </since_tizen>
1157 protected override void Dispose(DisposeTypes type)
1164 if (type == DisposeTypes.Explicit)
1167 //Release your own managed resources here.
1168 //You should release all of your own disposable objects here.
1171 borderSelector?.Reset(this);
1172 resourceUrlSelector?.Reset(this);
1178 /// This will not be public opened.
1179 [EditorBrowsable(EditorBrowsableState.Never)]
1180 protected override void ReleaseSwigCPtr(System.Runtime.InteropServices.HandleRef swigCPtr)
1182 Interop.ImageView.DeleteImageView(swigCPtr);
1185 // Callback for View ResourceReady signal
1186 private void OnResourceReady(IntPtr data)
1188 ResourceReadyEventArgs e = new ResourceReadyEventArgs();
1191 e.View = Registry.GetManagedBaseHandleFromNativePtr(data) as View;
1194 if (_resourceReadyEventHandler != null)
1196 _resourceReadyEventHandler(this, e);
1200 private void SetResourceUrl(string value)
1202 value = (value == null ? "" : value);
1203 if (value.StartsWith("*Resource*"))
1205 string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
1206 value = value.Replace("*Resource*", resource);
1208 _resourceUrl = value;
1209 UpdateImage(ImageVisualProperty.URL, new PropertyValue(value));
1212 private void SetBorder(Rectangle value)
1218 _border = new Rectangle(value);
1219 UpdateImage(NpatchImageVisualProperty.Border, new PropertyValue(_border));
1222 private void UpdateImageMap(PropertyMap fromMap)
1224 PropertyMap imageMap = new PropertyMap();
1226 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
1227 image?.Get(imageMap);
1228 imageMap?.Merge(fromMap);
1229 PropertyValue setValue = new PropertyValue(imageMap);
1230 SetProperty(ImageView.Property.IMAGE, setValue);
1232 imageMap?.Dispose();
1234 setValue?.Dispose();
1237 private void UpdateImage(int key, PropertyValue value)
1239 PropertyMap imageMap = new PropertyMap();
1241 if (_alphaMaskUrl != null)
1243 PropertyValue alphaMaskUrl = new PropertyValue(_alphaMaskUrl);
1244 imageMap?.Insert(ImageVisualProperty.AlphaMaskURL, alphaMaskUrl);
1245 alphaMaskUrl?.Dispose();
1248 if (string.IsNullOrEmpty(_resourceUrl))
1250 PropertyValue resourceUrl = new PropertyValue(_resourceUrl);
1251 imageMap?.Insert(ImageVisualProperty.URL, resourceUrl);
1252 PropertyValue setValue = new PropertyValue(imageMap);
1253 SetProperty(ImageView.Property.IMAGE, setValue);
1254 resourceUrl?.Dispose();
1255 setValue?.Dispose();
1259 if (_border == null)
1261 PropertyValue image = new PropertyValue((int)Visual.Type.Image);
1262 imageMap?.Insert(Visual.Property.Type, image);
1267 PropertyValue nPatch = new PropertyValue((int)Visual.Type.NPatch);
1268 imageMap?.Insert(Visual.Property.Type, nPatch);
1270 PropertyValue border = new PropertyValue(_border);
1271 imageMap?.Insert(NpatchImageVisualProperty.Border, border);
1275 if(key != Visual.Property.VisualFittingMode && _fittingMode != VisualFittingModeType.Fill)
1277 PropertyValue fittingMode = new PropertyValue((int)_fittingMode);
1278 imageMap?.Insert(Visual.Property.VisualFittingMode, fittingMode);
1279 fittingMode?.Dispose();
1282 PropertyValue synchronousLoading = new PropertyValue(_synchronousLoading);
1283 imageMap?.Insert(NpatchImageVisualProperty.SynchronousLoading, synchronousLoading);
1284 synchronousLoading?.Dispose();
1286 if (backgroundExtraData != null && backgroundExtraData.CornerRadius != null)
1288 using (var cornerRadius = new PropertyValue(backgroundExtraData.CornerRadius))
1289 using (var cornerRadiusPolicy = new PropertyValue((int)backgroundExtraData.CornerRadiusPolicy))
1291 imageMap.Insert(Visual.Property.CornerRadius, cornerRadius);
1292 imageMap.Insert(Visual.Property.CornerRadiusPolicy, new PropertyValue((int)(backgroundExtraData.CornerRadiusPolicy)));
1296 if (backgroundExtraData != null && backgroundExtraData.BorderlineWidth > 0.0f)
1298 using (var borderlineWidth = new PropertyValue(backgroundExtraData.BorderlineWidth))
1299 using (var borderlineColor = new PropertyValue(backgroundExtraData.BorderlineColor))
1300 using (var borderlineOffset = new PropertyValue(backgroundExtraData.BorderlineOffset))
1302 imageMap.Insert(Visual.Property.BorderlineWidth, borderlineWidth);
1303 imageMap.Insert(Visual.Property.BorderlineColor, borderlineColor);
1304 imageMap.Insert(Visual.Property.BorderlineOffset, borderlineOffset);
1310 imageMap?.Insert(key, value);
1313 // Do Fitting Buffer when desired dimension is set
1314 if (_desired_width != -1 && _desired_height != -1)
1316 if (_resourceUrl != null)
1318 Size2D imageSize = ImageLoader.GetOriginalImageSize(_resourceUrl, true);
1319 if( imageSize.Height > 0 && imageSize.Width > 0 && _desired_width > 0 && _desired_height > 0 )
1321 int adjustedDesiredWidth, adjustedDesiredHeight;
1322 float aspectOfDesiredSize = (float)_desired_height / (float)_desired_width;
1323 float aspectOfImageSize = (float)imageSize.Height / (float)imageSize.Width;
1324 if (aspectOfImageSize > aspectOfDesiredSize)
1326 adjustedDesiredWidth = _desired_width;
1327 adjustedDesiredHeight = imageSize.Height * _desired_width / imageSize.Width;
1331 adjustedDesiredWidth = imageSize.Width * _desired_height / imageSize.Height;
1332 adjustedDesiredHeight = _desired_height;
1335 PropertyValue returnWidth = new PropertyValue(adjustedDesiredWidth);
1336 imageMap?.Insert(ImageVisualProperty.DesiredWidth, returnWidth);
1337 returnWidth?.Dispose();
1338 PropertyValue returnHeight = new PropertyValue(adjustedDesiredHeight);
1339 imageMap?.Insert(ImageVisualProperty.DesiredHeight, returnHeight);
1340 returnHeight?.Dispose();
1341 PropertyValue scaleToFit = new PropertyValue((int)FittingModeType.ScaleToFill);
1342 imageMap?.Insert(ImageVisualProperty.FittingMode, scaleToFit);
1343 scaleToFit?.Dispose();
1347 Tizen.Log.Fatal("NUI", "[ERROR] Can't use DesiredSize when ImageLoading is failed.");
1349 imageSize?.Dispose();
1353 UpdateImageMap(imageMap);
1355 imageMap?.Dispose();
1360 private void OnResourceLoaded(IntPtr view)
1362 ResourceLoadedEventArgs e = new ResourceLoadedEventArgs();
1363 e.Status = (ResourceLoadingStatusType)Interop.View.GetVisualResourceStatus(this.SwigCPtr, Property.IMAGE);
1365 if (_resourceLoadedEventHandler != null)
1367 _resourceLoadedEventHandler(this, e);
1372 /// Event arguments of resource ready.
1374 /// <since_tizen> 3 </since_tizen>
1375 public class ResourceReadyEventArgs : EventArgs
1380 /// The view whose resource is ready.
1382 /// <since_tizen> 3 </since_tizen>
1396 internal class ResourceLoadedEventArgs : EventArgs
1398 private ResourceLoadingStatusType status = ResourceLoadingStatusType.Invalid;
1399 public ResourceLoadingStatusType Status
1412 internal new class Property
1414 internal static readonly int IMAGE = Interop.ImageView.ImageGet();
1415 internal static readonly int PreMultipliedAlpha = Interop.ImageView.PreMultipliedAlphaGet();
1416 internal static readonly int PixelArea = Interop.ImageView.PixelAreaGet();
1419 private enum ImageType
1422 /// For Normal Image.
1427 /// For normal image, with synchronous loading and orientation correction property
1432 /// For nine-patch image
1437 private void OnBorderChanged(int x, int y, int width, int height)
1439 Border = new Rectangle(x, y, width, height);
1441 private void OnPixelAreaChanged(float x, float y, float z, float w)
1443 PixelArea = new RelativeVector4(x, y, z, w);
1446 private class ImageLayout : LayoutItem
1449 /// Gets or sets the mode to adjust view size to preserve the aspect ratio of the image resource.
1450 /// 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.
1452 [EditorBrowsable(EditorBrowsableState.Never)]
1453 public bool AdjustViewSize
1457 return (Owner as ImageView)?.AdjustViewSize ?? false;
1461 if (Owner is ImageView imageView)
1463 imageView.AdjustViewSize = value;
1469 [EditorBrowsable(EditorBrowsableState.Never)]
1470 protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
1472 // To not change the view size by DALi
1473 Owner.WidthResizePolicy = ResizePolicyType.Fixed;
1474 Owner.HeightResizePolicy = ResizePolicyType.Fixed;
1476 float specWidth = widthMeasureSpec.Size.AsDecimal();
1477 float specHeight = heightMeasureSpec.Size.AsDecimal();
1478 float naturalWidth = Owner.NaturalSize.Width;
1479 float naturalHeight = Owner.NaturalSize.Height;
1480 float minWidth = Owner.MinimumSize.Width;
1481 float maxWidth = Owner.MaximumSize.Width;
1482 float minHeight = Owner.MinimumSize.Height;
1483 float maxHeight = Owner.MaximumSize.Height;
1484 float aspectRatio = (naturalWidth > 0) ? (naturalHeight / naturalWidth) : 0;
1486 // Assume that the new width and height are given from the view's suggested size by default.
1487 float newWidth = Math.Min(Math.Max(naturalWidth, minWidth), (maxWidth < 0 ? Int32.MaxValue : maxWidth));
1488 float newHeight = Math.Min(Math.Max(naturalHeight, minHeight), (maxHeight < 0 ? Int32.MaxValue : maxHeight));
1490 // The width and height measure specs are going to be used to set measured size.
1491 // Mark that the measure specs are changed by default to update measure specs later.
1492 bool widthSpecChanged = true;
1493 bool heightSpecChanged = true;
1495 if (widthMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly)
1497 newWidth = specWidth;
1498 widthSpecChanged = false;
1500 if (heightMeasureSpec.Mode != MeasureSpecification.ModeType.Exactly)
1502 if ((AdjustViewSize) && (aspectRatio > 0))
1504 newHeight = newWidth * aspectRatio;
1509 if (heightMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly)
1511 newHeight = specHeight;
1512 heightSpecChanged = false;
1514 if (widthMeasureSpec.Mode != MeasureSpecification.ModeType.Exactly)
1516 if ((AdjustViewSize) && (aspectRatio > 0))
1518 newWidth = newHeight / aspectRatio;
1523 if (widthSpecChanged)
1525 widthMeasureSpec = new MeasureSpecification(new LayoutLength(newWidth), MeasureSpecification.ModeType.Exactly);
1528 if (heightSpecChanged)
1530 heightMeasureSpec = new MeasureSpecification(new LayoutLength(newHeight), MeasureSpecification.ModeType.Exactly);
1533 MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK;
1534 MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK;
1536 SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(newWidth), widthMeasureSpec, childWidthState),
1537 ResolveSizeAndState(new LayoutLength(newHeight), heightMeasureSpec, childHeightState));