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)
131 /// Create internal layout of ImageView
133 internal static LayoutItem CreateImageLayout()
135 return new ImageLayout();
138 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
139 private delegate void ResourceReadyEventCallbackType(IntPtr data);
140 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
141 private delegate void _resourceLoadedCallbackType(IntPtr view);
144 /// An event for ResourceReady signal which can be used to subscribe or unsubscribe the event handler.<br />
145 /// This signal is emitted after all resources required by a control are loaded and ready.<br />
146 /// Most resources are only loaded when the control is placed on the stage.<br />
148 /// <since_tizen> 3 </since_tizen>
149 public event EventHandler<ResourceReadyEventArgs> ResourceReady
153 if (_resourceReadyEventHandler == null)
155 _resourceReadyEventCallback = OnResourceReady;
156 ViewResourceReadySignal resourceReadySignal = ResourceReadySignal(this);
157 resourceReadySignal?.Connect(_resourceReadyEventCallback);
158 resourceReadySignal?.Dispose();
161 _resourceReadyEventHandler += value;
166 _resourceReadyEventHandler -= value;
168 ViewResourceReadySignal resourceReadySignal = ResourceReadySignal(this);
169 if (_resourceReadyEventHandler == null && resourceReadySignal?.Empty() == false)
171 resourceReadySignal?.Disconnect(_resourceReadyEventCallback);
173 resourceReadySignal?.Dispose();
177 internal event EventHandler<ResourceLoadedEventArgs> ResourceLoaded
181 if (_resourceLoadedEventHandler == null)
183 _resourceLoadedCallback = OnResourceLoaded;
184 ViewResourceReadySignal resourceReadySignal = this.ResourceReadySignal(this);
185 resourceReadySignal?.Connect(_resourceLoadedCallback);
186 resourceReadySignal?.Dispose();
189 _resourceLoadedEventHandler += value;
193 _resourceLoadedEventHandler -= value;
194 ViewResourceReadySignal resourceReadySignal = this.ResourceReadySignal(this);
195 if (_resourceLoadedEventHandler == null && resourceReadySignal?.Empty() == false)
197 resourceReadySignal?.Disconnect(_resourceLoadedCallback);
199 resourceReadySignal?.Dispose();
204 /// Enumeration for LoadingStatus of image.
206 /// <since_tizen> 5 </since_tizen>
207 public enum LoadingStatusType
210 /// Loading preparing status.
212 /// <since_tizen> 5 </since_tizen>
215 /// Loading ready status.
217 /// <since_tizen> 5 </since_tizen>
220 /// Loading failed status.
222 /// <since_tizen> 5 </since_tizen>
227 /// ImageView ResourceUrl, type string.
228 /// This is one of mandatory property. Even if not set or null set, it sets empty string ("") internally.
229 /// When it is set as null, it gives empty string ("") to be read.
231 /// <since_tizen> 3 </since_tizen>
232 public string ResourceUrl
236 return (string)GetValue(ResourceUrlProperty);
240 SetValue(ResourceUrlProperty, value);
241 NotifyPropertyChanged();
246 /// This will be deprecated, please use Image instead. <br />
247 /// ImageView ImageMap, type PropertyMap: string if it is a URL, map otherwise.
249 /// <since_tizen> 3 </since_tizen>
250 [Obsolete("Please do not use! This will be deprecated! Please use Image property instead!")]
251 [EditorBrowsable(EditorBrowsableState.Never)]
252 public PropertyMap ImageMap
256 return GetValue(ImageMapProperty) as PropertyMap;
260 SetValue(ImageMapProperty, value);
261 NotifyPropertyChanged();
264 private PropertyMap InternalImageMap
270 PropertyMap returnValue = new PropertyMap();
271 PropertyValue image = GetProperty(ImageView.Property.IMAGE);
272 image?.Get(returnValue);
285 PropertyValue setValue = new Tizen.NUI.PropertyValue(value);
286 SetProperty(ImageView.Property.IMAGE, setValue);
287 NotifyPropertyChanged();
294 /// ImageView Image, type PropertyMap: string if it is a URL, map otherwise.
297 /// This PropertyMap use a <see cref="ImageVisualProperty"/>. <br />
298 /// See <see cref="ImageVisualProperty"/> for a detailed description. <br />
299 /// you can also use <see cref="Visual.Property"/>. <br />
300 /// See <see cref="Visual.Property"/> for a detailed description. <br />
303 /// The following example demonstrates how to use the Image property.
305 /// PropertyMap map = new PropertyMap();
306 /// map.Insert(Visual.Property.Type, new PropertyValue((int)Visual.Type.Image));
307 /// map.Insert(ImageVisualProperty.AlphaMaskURL, new PropertyValue(url));
308 /// map.Insert(ImageVisualProperty.FittingMode, new PropertyValue((int)FittingModeType.ScaleToFill);
309 /// imageview.Image = map;
312 /// <since_tizen> 4 </since_tizen>
313 public PropertyMap Image
319 return (PropertyMap)GetValue(ImageProperty);
330 SetValue(ImageProperty, value);
331 NotifyPropertyChanged();
337 /// ImageView PreMultipliedAlpha, type Boolean.<br />
338 /// Image must be initialized.<br />
340 /// <since_tizen> 3 </since_tizen>
341 public bool PreMultipliedAlpha
345 return (bool)GetValue(PreMultipliedAlphaProperty);
349 SetValue(PreMultipliedAlphaProperty, value);
350 NotifyPropertyChanged();
355 /// ImageView PixelArea, type Vector4 (Animatable property).<br />
356 /// Pixel area is a relative value with the whole image area as [0.0, 0.0, 1.0, 1.0].<br />
359 /// The property cascade chaining set is possible. For example, this (imageView.PixelArea.X = 0.1f;) is possible.
361 /// <since_tizen> 3 </since_tizen>
362 public RelativeVector4 PixelArea
366 RelativeVector4 temp = (RelativeVector4)GetValue(PixelAreaProperty);
367 return new RelativeVector4(OnPixelAreaChanged, temp.X, temp.Y, temp.Z, temp.W);
371 SetValue(PixelAreaProperty, value);
372 NotifyPropertyChanged();
377 /// The border of the image in the order: left, right, bottom, top.<br />
378 /// If set, ImageMap will be ignored.<br />
379 /// For N-Patch images only.<br />
383 /// The property cascade chaining set is possible. For example, this (imageView.Border.X = 1;) is possible.
385 /// <since_tizen> 3 </since_tizen>
386 public Rectangle Border
390 Rectangle temp = (Rectangle)GetValue(BorderProperty);
397 return new Rectangle(OnBorderChanged, temp.X, temp.Y, temp.Width, temp.Height);
402 SetValue(BorderProperty, value);
403 NotifyPropertyChanged();
408 /// Gets or sets whether to draw the borders only (if true).<br />
409 /// If not specified, the default is false.<br />
410 /// For N-Patch images only.<br />
413 /// <since_tizen> 3 </since_tizen>
414 public bool BorderOnly
418 return (bool)GetValue(BorderOnlyProperty);
422 SetValue(BorderOnlyProperty, value);
423 NotifyPropertyChanged();
428 /// Gets or sets whether to synchronous loading the resourceurl of image.<br />
430 /// <since_tizen> 3 </since_tizen>
431 public bool SynchronosLoading
435 return SynchronousLoading;
439 SynchronousLoading = value;
444 /// Gets or sets whether to synchronous loading the resourceurl of image.<br />
446 /// This will be public opened in tizen_7.0 after ACR done. Before ACR, need to be hidden as inhouse API.
447 [EditorBrowsable(EditorBrowsableState.Never)]
448 public bool SynchronousLoading
452 return (bool)GetValue(SynchronousLoadingProperty);
456 SetValue(SynchronousLoadingProperty, value);
457 NotifyPropertyChanged();
462 /// Gets or sets whether to automatically correct the orientation of an image.<br />
464 /// <since_tizen> 5 </since_tizen>
465 public bool OrientationCorrection
469 return (bool)GetValue(OrientationCorrectionProperty);
473 SetValue(OrientationCorrectionProperty, value);
474 NotifyPropertyChanged();
479 /// Gets the loading state of the visual resource.
481 /// <since_tizen> 5 </since_tizen>
482 public ImageView.LoadingStatusType LoadingStatus
486 return (ImageView.LoadingStatusType)Interop.View.GetVisualResourceStatus(SwigCPtr, (int)Property.IMAGE);
491 /// Downcasts a handle to imageView handle.
493 /// <exception cref="ArgumentNullException"> Thrown when handle is null. </exception>
494 /// Please do not use! this will be deprecated!
495 /// Instead please use as keyword.
496 /// <since_tizen> 3 </since_tizen>
497 [Obsolete("Please do not use! This will be deprecated! Please use as keyword instead! " +
499 "BaseHandle handle = new ImageView(imagePath); " +
500 "ImageView image = handle as ImageView")]
501 [EditorBrowsable(EditorBrowsableState.Never)]
502 public static ImageView DownCast(BaseHandle handle)
506 throw new ArgumentNullException(nameof(handle));
508 ImageView ret = Registry.GetManagedBaseHandleFromNativePtr(handle) as ImageView;
509 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
514 /// Sets this ImageView from the given URL.<br />
515 /// If the URL is empty, ImageView will not display anything.<br />
517 /// <param name="url">The URL to the image resource to display.</param>
518 /// <exception cref="ArgumentNullException"> Thrown when url is null. </exception>
519 /// <since_tizen> 3 </since_tizen>
520 public void SetImage(string url)
524 throw new ArgumentNullException(nameof(url));
527 if (url.Contains(".json"))
529 Tizen.Log.Fatal("NUI", "[ERROR] Please DO NOT set lottie file in ImageView! This is temporary checking, will be removed soon!");
533 Interop.ImageView.SetImage(SwigCPtr, url);
534 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
540 /// Queries if all resources required by a control are loaded and ready.<br />
541 /// Most resources are only loaded when the control is placed on the stage.<br />
542 /// True if the resources are loaded and ready, false otherwise.<br />
544 /// <since_tizen> 3 </since_tizen>
545 public new bool IsResourceReady()
547 bool ret = Interop.View.IsResourceReady(SwigCPtr);
548 if (NDalicPINVOKE.SWIGPendingException.Pending)
549 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
554 /// Forcefully reloads the image. All the visuals using this image will reload to the latest image.
556 /// <since_tizen> 5 </since_tizen>
559 PropertyValue attributes = new PropertyValue(0);
560 this.DoAction(ImageView.Property.IMAGE, Property.ActionReload, attributes);
561 attributes?.Dispose();
565 /// Plays the animated GIF. This is also the default playback mode.
567 /// <since_tizen> 5 </since_tizen>
570 PropertyValue attributes = new PropertyValue(0);
571 this.DoAction(ImageView.Property.IMAGE, Property.ActionPlay, attributes);
572 attributes?.Dispose();
576 /// Pauses the animated GIF.
578 /// <since_tizen> 5 </since_tizen>
581 PropertyValue attributes = new PropertyValue(0);
582 this.DoAction(ImageView.Property.IMAGE, Property.ActionPause, attributes);
583 attributes?.Dispose();
587 /// Stops the animated GIF.
589 /// <since_tizen> 5 </since_tizen>
592 PropertyValue attributes = new PropertyValue(0);
593 this.DoAction(ImageView.Property.IMAGE, Property.ActionStop, attributes);
594 attributes?.Dispose();
598 /// Gets or sets the URL of the alpha mask.<br />
601 /// <since_tizen> 6</since_tizen>
602 [EditorBrowsable(EditorBrowsableState.Never)]
603 public string AlphaMaskURL
607 return GetValue(AlphaMaskURLProperty) as string;
611 SetValue(AlphaMaskURLProperty, value);
612 NotifyPropertyChanged();
616 private string InternalAlphaMaskURL
621 PropertyMap imageMap = new PropertyMap();
622 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
623 image?.Get(imageMap);
624 PropertyValue maskUrl = imageMap?.Find(ImageVisualProperty.AlphaMaskURL);
625 maskUrl?.Get(out ret);
641 _alphaMaskUrl = value;
643 PropertyValue setValue = new PropertyValue(value);
644 UpdateImage(ImageVisualProperty.AlphaMaskURL, setValue);
651 /// Whether to crop image to mask or scale mask to fit image.
653 /// <since_tizen> 6 </since_tizen>
654 public bool CropToMask
658 return (bool)GetValue(CropToMaskProperty);
662 SetValue(CropToMaskProperty, value);
663 NotifyPropertyChanged();
666 private bool InternalCropToMask
671 PropertyMap imageMap = new PropertyMap();
672 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
673 image?.Get(imageMap);
674 PropertyValue cropUrl = imageMap?.Find(ImageVisualProperty.CropToMask);
675 cropUrl?.Get(out ret);
685 PropertyValue setValue = new PropertyValue(value);
686 UpdateImage(ImageVisualProperty.CropToMask, setValue);
691 internal VisualFittingModeType CovertFittingModetoVisualFittingMode(FittingModeType value)
695 case FittingModeType.ShrinkToFit:
696 return VisualFittingModeType.FitKeepAspectRatio;
697 case FittingModeType.ScaleToFill:
698 return VisualFittingModeType.OverFitKeepAspectRatio;
699 case FittingModeType.Center:
700 return VisualFittingModeType.Center;
701 case FittingModeType.Fill:
702 return VisualFittingModeType.Fill;
703 case FittingModeType.FitHeight:
704 return VisualFittingModeType.FitHeight;
705 case FittingModeType.FitWidth:
706 return VisualFittingModeType.FitHeight;
708 return VisualFittingModeType.Fill;
712 internal FittingModeType ConvertVisualFittingModetoFittingMode(VisualFittingModeType value)
716 case VisualFittingModeType.FitKeepAspectRatio:
717 return FittingModeType.ShrinkToFit;
718 case VisualFittingModeType.OverFitKeepAspectRatio:
719 return FittingModeType.ScaleToFill;
720 case VisualFittingModeType.Center:
721 return FittingModeType.Center;
722 case VisualFittingModeType.Fill:
723 return FittingModeType.Fill;
724 case VisualFittingModeType.FitHeight:
725 return FittingModeType.FitHeight;
726 case VisualFittingModeType.FitWidth:
727 return FittingModeType.FitWidth;
729 return FittingModeType.ShrinkToFit;
734 /// Gets or sets fitting options used when resizing images to fit.<br />
735 /// If not supplied, the default is FittingModeType.Fill.<br />
736 /// For normal quad images only.<br />
739 /// <since_tizen> 6 </since_tizen>
740 [EditorBrowsable(EditorBrowsableState.Never)]
741 public FittingModeType FittingMode
745 return (FittingModeType)GetValue(FittingModeProperty);
749 SetValue(FittingModeProperty, value);
750 NotifyPropertyChanged();
754 private FittingModeType InternalFittingMode
758 int ret = (int)_fittingMode;
759 PropertyMap imageMap = new PropertyMap();
760 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
761 image?.Get(imageMap);
762 PropertyValue fittingMode = imageMap?.Find(Visual.Property.VisualFittingMode);
763 fittingMode?.Get(out ret);
764 _fittingMode = (VisualFittingModeType)ret;
768 fittingMode?.Dispose();
770 return ConvertVisualFittingModetoFittingMode((VisualFittingModeType)ret);
774 VisualFittingModeType ret = CovertFittingModetoVisualFittingMode(value);
775 PropertyValue setValue = new PropertyValue((int)ret);
776 if(_fittingMode != ret)
779 UpdateImage(Visual.Property.VisualFittingMode, setValue);
788 /// Gets or sets the desired image width.<br />
789 /// If not specified, the actual image width is used.<br />
790 /// For normal quad images only.<br />
793 /// <since_tizen> 6 </since_tizen>
794 [EditorBrowsable(EditorBrowsableState.Never)]
795 public int DesiredWidth
799 return (int)GetValue(DesiredWidthProperty);
803 SetValue(DesiredWidthProperty, value);
804 NotifyPropertyChanged();
807 private int InternalDesiredWidth
811 PropertyMap imageMap = new PropertyMap();
812 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
813 image?.Get(imageMap);
814 PropertyValue desireWidth = imageMap?.Find(ImageVisualProperty.DesiredWidth);
815 desireWidth?.Get(out _desired_width);
819 desireWidth?.Dispose();
821 return _desired_width;
825 if (_desired_width != value)
827 _desired_width = value;
828 UpdateImage(0, null);
834 /// Gets or sets the desired image height.<br />
835 /// If not specified, the actual image height is used.<br />
836 /// For normal quad images only.<br />
839 /// <since_tizen> 6 </since_tizen>
840 [EditorBrowsable(EditorBrowsableState.Never)]
841 public int DesiredHeight
845 return (int)GetValue(DesiredHeightProperty);
849 SetValue(DesiredHeightProperty, value);
850 NotifyPropertyChanged();
853 private int InternalDesiredHeight
857 PropertyMap imageMap = new PropertyMap();
858 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
859 image?.Get(imageMap);
860 PropertyValue desireheight = imageMap?.Find(ImageVisualProperty.DesiredHeight);
861 desireheight?.Get(out _desired_height);
865 desireheight?.Dispose();
867 return _desired_height;
871 if (_desired_height != value)
873 _desired_height = value;
874 UpdateImage(0, null);
880 /// Gets or sets ReleasePolicy for image.<br />
881 /// If not supplied, the default is ReleasePolicyType.Detached.<br />
883 [EditorBrowsable(EditorBrowsableState.Never)]
884 public ReleasePolicyType ReleasePolicy
888 return (ReleasePolicyType)GetValue(ReleasePolicyProperty);
892 SetValue(ReleasePolicyProperty, value);
893 NotifyPropertyChanged();
897 private ReleasePolicyType InternalReleasePolicy
901 int ret = (int)ReleasePolicyType.Detached;
902 PropertyMap imageMap = new PropertyMap();
903 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
904 image?.Get(imageMap);
905 PropertyValue releasePoli = imageMap?.Find(ImageVisualProperty.ReleasePolicy);
906 releasePoli?.Get(out ret);
910 releasePoli?.Dispose();
912 return (ReleasePolicyType)ret;
916 PropertyValue setValue = new PropertyValue((int)value);
917 UpdateImage(ImageVisualProperty.ReleasePolicy, setValue);
923 /// Gets or sets the wrap mode for the u coordinate.<br />
924 /// It decides how the texture should be sampled when the u coordinate exceeds the range of 0.0 to 1.0.<br />
925 /// If not specified, the default is WrapModeType.Default(CLAMP).<br />
926 /// For normal quad images only.<br />
929 /// <since_tizen> 6 </since_tizen>
930 [EditorBrowsable(EditorBrowsableState.Never)]
931 public WrapModeType WrapModeU
935 return (WrapModeType)GetValue(WrapModeUProperty);
939 SetValue(WrapModeUProperty, value);
940 NotifyPropertyChanged();
944 private WrapModeType InternalWrapModeU
948 int ret = (int)WrapModeType.Default;
949 PropertyMap imageMap = new PropertyMap();
950 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
951 image?.Get(imageMap);
952 PropertyValue warpModeU = imageMap?.Find(ImageVisualProperty.WrapModeU);
953 warpModeU?.Get(out ret);
957 warpModeU?.Dispose();
959 return (WrapModeType)ret;
963 PropertyValue setValue = new PropertyValue((int)value);
964 UpdateImage(ImageVisualProperty.WrapModeU, setValue);
970 /// Gets or sets the wrap mode for the v coordinate.<br />
971 /// It decides how the texture should be sampled when the v coordinate exceeds the range of 0.0 to 1.0.<br />
972 /// 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 />
973 /// If not specified, the default is WrapModeType.Default(CLAMP).<br />
974 /// For normal quad images only.
977 /// <since_tizen> 6 </since_tizen>
978 [EditorBrowsable(EditorBrowsableState.Never)]
979 public WrapModeType WrapModeV
983 return (WrapModeType)GetValue(WrapModeVProperty);
987 SetValue(WrapModeVProperty, value);
988 NotifyPropertyChanged();
992 private WrapModeType InternalWrapModeV
996 int ret = (int)WrapModeType.Default;
997 PropertyMap imageMap = new PropertyMap();
998 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
999 image?.Get(imageMap);
1000 PropertyValue wrapModeV = imageMap?.Find(ImageVisualProperty.WrapModeV);
1001 wrapModeV?.Get(out ret);
1003 imageMap?.Dispose();
1005 wrapModeV?.Dispose();
1007 return (WrapModeType)ret;
1011 PropertyValue setValue = new PropertyValue((int)value);
1012 UpdateImage(ImageVisualProperty.WrapModeV, setValue);
1013 setValue?.Dispose();
1018 /// Gets or sets the mode to adjust view size to preserve the aspect ratio of the image resource.
1019 /// 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.
1020 /// AdjustViewSize works only if ImageView is added to a View having Layout.
1022 [EditorBrowsable(EditorBrowsableState.Never)]
1023 public bool AdjustViewSize
1027 return (bool)GetValue(AdjustViewSizeProperty);
1031 SetValue(AdjustViewSizeProperty, value);
1032 NotifyPropertyChanged();
1035 private bool adjustViewSize = false;
1037 internal Selector<string> ResourceUrlSelector
1039 get => GetSelector<string>(resourceUrlSelector, ImageView.ResourceUrlProperty);
1042 resourceUrlSelector?.Reset(this);
1043 if (value == null) return;
1045 if (value.HasAll()) SetResourceUrl(value.All);
1046 else resourceUrlSelector = new TriggerableSelector<string>(this, value, SetResourceUrl, true);
1051 /// Get attributes, it is abstract function and must be override.
1053 [EditorBrowsable(EditorBrowsableState.Never)]
1054 protected override ViewStyle CreateViewStyle()
1056 return new ImageViewStyle();
1059 internal void SetImage(string url, Uint16Pair size)
1061 if (url.Contains(".json"))
1063 Tizen.Log.Fatal("NUI", "[ERROR] Please DO NOT set lottie file in ImageView! This is temporary checking, will be removed soon!");
1067 Interop.ImageView.SetImage(SwigCPtr, url, Uint16Pair.getCPtr(size));
1068 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
1073 internal ViewResourceReadySignal ResourceReadySignal(View view)
1075 ViewResourceReadySignal ret = new ViewResourceReadySignal(Interop.View.ResourceReadySignal(View.getCPtr(view)), false);
1076 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
1080 internal override void ApplyCornerRadius()
1082 base.ApplyCornerRadius();
1084 UpdateImage(0, null);
1087 internal override void ApplyBorderline()
1089 base.ApplyBorderline();
1091 // Apply borderline to IMAGE.
1092 if (backgroundExtraData != null)
1094 var borderlineColor = backgroundExtraData.BorderlineColor == null ? new PropertyValue(Color.Black) : new PropertyValue(backgroundExtraData.BorderlineColor);
1096 // Apply to the image visual
1097 PropertyMap imageMap = new PropertyMap();
1098 PropertyValue imageValue = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
1099 if (imageValue.Get(imageMap) && !imageMap.Empty())
1101 imageMap[Visual.Property.BorderlineWidth] = new PropertyValue(backgroundExtraData.BorderlineWidth);
1102 imageMap[Visual.Property.BorderlineColor] = borderlineColor;
1103 imageMap[Visual.Property.BorderlineOffset] = new PropertyValue(backgroundExtraData.BorderlineOffset);
1104 var temp = new PropertyValue(imageMap);
1105 Tizen.NUI.Object.SetProperty(SwigCPtr, ImageView.Property.IMAGE, temp);
1109 imageValue.Dispose();
1110 borderlineColor.Dispose();
1113 UpdateImage(0, null);
1116 internal ResourceLoadingStatusType GetResourceStatus()
1118 return (ResourceLoadingStatusType)Interop.View.GetVisualResourceStatus(this.SwigCPtr, Property.IMAGE);
1122 /// you can override it to clean-up your own resources.
1124 /// <param name="type">DisposeTypes</param>
1125 /// <since_tizen> 3 </since_tizen>
1126 protected override void Dispose(DisposeTypes type)
1133 if (type == DisposeTypes.Explicit)
1136 //Release your own managed resources here.
1137 //You should release all of your own disposable objects here.
1140 borderSelector?.Reset(this);
1141 resourceUrlSelector?.Reset(this);
1147 /// This will not be public opened.
1148 [EditorBrowsable(EditorBrowsableState.Never)]
1149 protected override void ReleaseSwigCPtr(System.Runtime.InteropServices.HandleRef swigCPtr)
1151 Interop.ImageView.DeleteImageView(swigCPtr);
1154 // Callback for View ResourceReady signal
1155 private void OnResourceReady(IntPtr data)
1157 ResourceReadyEventArgs e = new ResourceReadyEventArgs();
1160 e.View = Registry.GetManagedBaseHandleFromNativePtr(data) as View;
1163 if (_resourceReadyEventHandler != null)
1165 _resourceReadyEventHandler(this, e);
1169 private void SetResourceUrl(string value)
1171 value = (value == null ? "" : value);
1172 if (value.StartsWith("*Resource*"))
1174 string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
1175 value = value.Replace("*Resource*", resource);
1177 _resourceUrl = value;
1178 UpdateImage(ImageVisualProperty.URL, new PropertyValue(value));
1181 private void SetBorder(Rectangle value)
1187 _border = new Rectangle(value);
1188 UpdateImage(NpatchImageVisualProperty.Border, new PropertyValue(_border));
1191 private void UpdateImageMap(PropertyMap fromMap)
1193 PropertyMap imageMap = new PropertyMap();
1195 PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
1196 image?.Get(imageMap);
1197 imageMap?.Merge(fromMap);
1198 PropertyValue setValue = new PropertyValue(imageMap);
1199 SetProperty(ImageView.Property.IMAGE, setValue);
1201 imageMap?.Dispose();
1203 setValue?.Dispose();
1206 private void UpdateImage(int key, PropertyValue value)
1208 PropertyMap imageMap = new PropertyMap();
1210 if (_alphaMaskUrl != null)
1212 PropertyValue alphaMaskUrl = new PropertyValue(_alphaMaskUrl);
1213 imageMap?.Insert(ImageVisualProperty.AlphaMaskURL, alphaMaskUrl);
1214 alphaMaskUrl?.Dispose();
1217 if (string.IsNullOrEmpty(_resourceUrl))
1219 PropertyValue resourceUrl = new PropertyValue(_resourceUrl);
1220 imageMap?.Insert(ImageVisualProperty.URL, resourceUrl);
1221 PropertyValue setValue = new PropertyValue(imageMap);
1222 SetProperty(ImageView.Property.IMAGE, setValue);
1223 resourceUrl?.Dispose();
1224 setValue?.Dispose();
1228 if (_border == null)
1230 PropertyValue image = new PropertyValue((int)Visual.Type.Image);
1231 imageMap?.Insert(Visual.Property.Type, image);
1236 PropertyValue nPatch = new PropertyValue((int)Visual.Type.NPatch);
1237 imageMap?.Insert(Visual.Property.Type, nPatch);
1239 PropertyValue border = new PropertyValue(_border);
1240 imageMap?.Insert(NpatchImageVisualProperty.Border, border);
1244 if(key != Visual.Property.VisualFittingMode && _fittingMode != VisualFittingModeType.Fill)
1246 PropertyValue fittingMode = new PropertyValue((int)_fittingMode);
1247 imageMap?.Insert(Visual.Property.VisualFittingMode, fittingMode);
1248 fittingMode?.Dispose();
1251 PropertyValue synchronousLoading = new PropertyValue(_synchronousLoading);
1252 imageMap?.Insert(NpatchImageVisualProperty.SynchronousLoading, synchronousLoading);
1253 synchronousLoading?.Dispose();
1255 if (backgroundExtraData != null && backgroundExtraData.CornerRadius != null)
1257 using (var cornerRadius = new PropertyValue(backgroundExtraData.CornerRadius))
1258 using (var cornerRadiusPolicy = new PropertyValue((int)backgroundExtraData.CornerRadiusPolicy))
1260 imageMap.Insert(Visual.Property.CornerRadius, cornerRadius);
1261 imageMap.Insert(Visual.Property.CornerRadiusPolicy, new PropertyValue((int)(backgroundExtraData.CornerRadiusPolicy)));
1265 if (backgroundExtraData != null && backgroundExtraData.BorderlineWidth > 0.0f)
1267 using (var borderlineWidth = new PropertyValue(backgroundExtraData.BorderlineWidth))
1268 using (var borderlineColor = new PropertyValue(backgroundExtraData.BorderlineColor))
1269 using (var borderlineOffset = new PropertyValue(backgroundExtraData.BorderlineOffset))
1271 imageMap.Insert(Visual.Property.BorderlineWidth, borderlineWidth);
1272 imageMap.Insert(Visual.Property.BorderlineColor, borderlineColor);
1273 imageMap.Insert(Visual.Property.BorderlineOffset, borderlineOffset);
1279 imageMap?.Insert(key, value);
1282 // Do Fitting Buffer when desired dimension is set
1283 if (_desired_width != -1 && _desired_height != -1)
1285 if (_resourceUrl != null)
1287 Size2D imageSize = ImageLoader.GetOriginalImageSize(_resourceUrl, true);
1288 if( imageSize.Height > 0 && imageSize.Width > 0 && _desired_width > 0 && _desired_height > 0 )
1290 int adjustedDesiredWidth, adjustedDesiredHeight;
1291 float aspectOfDesiredSize = (float)_desired_height / (float)_desired_width;
1292 float aspectOfImageSize = (float)imageSize.Height / (float)imageSize.Width;
1293 if (aspectOfImageSize > aspectOfDesiredSize)
1295 adjustedDesiredWidth = _desired_width;
1296 adjustedDesiredHeight = imageSize.Height * _desired_width / imageSize.Width;
1300 adjustedDesiredWidth = imageSize.Width * _desired_height / imageSize.Height;
1301 adjustedDesiredHeight = _desired_height;
1304 PropertyValue returnWidth = new PropertyValue(adjustedDesiredWidth);
1305 imageMap?.Insert(ImageVisualProperty.DesiredWidth, returnWidth);
1306 returnWidth?.Dispose();
1307 PropertyValue returnHeight = new PropertyValue(adjustedDesiredHeight);
1308 imageMap?.Insert(ImageVisualProperty.DesiredHeight, returnHeight);
1309 returnHeight?.Dispose();
1310 PropertyValue scaleToFit = new PropertyValue((int)FittingModeType.ScaleToFill);
1311 imageMap?.Insert(ImageVisualProperty.FittingMode, scaleToFit);
1312 scaleToFit?.Dispose();
1316 Tizen.Log.Fatal("NUI", "[ERROR] Can't use DesiredSize when ImageLoading is failed.");
1318 imageSize?.Dispose();
1322 UpdateImageMap(imageMap);
1324 imageMap?.Dispose();
1329 private void OnResourceLoaded(IntPtr view)
1331 ResourceLoadedEventArgs e = new ResourceLoadedEventArgs();
1332 e.Status = (ResourceLoadingStatusType)Interop.View.GetVisualResourceStatus(this.SwigCPtr, Property.IMAGE);
1334 if (_resourceLoadedEventHandler != null)
1336 _resourceLoadedEventHandler(this, e);
1341 /// Event arguments of resource ready.
1343 /// <since_tizen> 3 </since_tizen>
1344 public class ResourceReadyEventArgs : EventArgs
1349 /// The view whose resource is ready.
1351 /// <since_tizen> 3 </since_tizen>
1365 internal class ResourceLoadedEventArgs : EventArgs
1367 private ResourceLoadingStatusType status = ResourceLoadingStatusType.Invalid;
1368 public ResourceLoadingStatusType Status
1381 internal new class Property
1383 internal static readonly int IMAGE = Interop.ImageView.ImageGet();
1384 internal static readonly int PreMultipliedAlpha = Interop.ImageView.PreMultipliedAlphaGet();
1385 internal static readonly int PixelArea = Interop.ImageView.PixelAreaGet();
1386 internal static readonly int ActionReload = Interop.ImageView.ImageVisualActionReloadGet();
1387 internal static readonly int ActionPlay = Interop.ImageView.ImageVisualActionPlayGet();
1388 internal static readonly int ActionPause = Interop.ImageView.ImageVisualActionPauseGet();
1389 internal static readonly int ActionStop = Interop.ImageView.ImageVisualActionStopGet();
1392 private enum ImageType
1395 /// For Normal Image.
1400 /// For normal image, with synchronous loading and orientation correction property
1405 /// For nine-patch image
1410 private void OnBorderChanged(int x, int y, int width, int height)
1412 Border = new Rectangle(x, y, width, height);
1414 private void OnPixelAreaChanged(float x, float y, float z, float w)
1416 PixelArea = new RelativeVector4(x, y, z, w);
1419 private class ImageLayout : LayoutItem
1422 /// Gets or sets the mode to adjust view size to preserve the aspect ratio of the image resource.
1423 /// 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.
1425 [EditorBrowsable(EditorBrowsableState.Never)]
1426 public bool AdjustViewSize
1430 return (Owner as ImageView)?.AdjustViewSize ?? false;
1434 if (Owner is ImageView imageView)
1436 imageView.AdjustViewSize = value;
1442 [EditorBrowsable(EditorBrowsableState.Never)]
1443 protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
1445 // To not change the view size by DALi
1446 Owner.WidthResizePolicy = ResizePolicyType.Fixed;
1447 Owner.HeightResizePolicy = ResizePolicyType.Fixed;
1449 float specWidth = widthMeasureSpec.Size.AsDecimal();
1450 float specHeight = heightMeasureSpec.Size.AsDecimal();
1451 float naturalWidth = Owner.NaturalSize.Width;
1452 float naturalHeight = Owner.NaturalSize.Height;
1453 float minWidth = Owner.MinimumSize.Width;
1454 float maxWidth = Owner.MaximumSize.Width;
1455 float minHeight = Owner.MinimumSize.Height;
1456 float maxHeight = Owner.MaximumSize.Height;
1457 float aspectRatio = (naturalWidth > 0) ? (naturalHeight / naturalWidth) : 0;
1459 // Assume that the new width and height are given from the view's suggested size by default.
1460 float newWidth = Math.Min(Math.Max(naturalWidth, minWidth), (maxWidth < 0 ? Int32.MaxValue : maxWidth));
1461 float newHeight = Math.Min(Math.Max(naturalHeight, minHeight), (maxHeight < 0 ? Int32.MaxValue : maxHeight));
1463 // The width and height measure specs are going to be used to set measured size.
1464 // Mark that the measure specs are changed by default to update measure specs later.
1465 bool widthSpecChanged = true;
1466 bool heightSpecChanged = true;
1468 if (widthMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly)
1470 newWidth = specWidth;
1471 widthSpecChanged = false;
1473 if (heightMeasureSpec.Mode != MeasureSpecification.ModeType.Exactly)
1475 if ((AdjustViewSize) && (aspectRatio > 0))
1477 newHeight = newWidth * aspectRatio;
1482 if (heightMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly)
1484 newHeight = specHeight;
1485 heightSpecChanged = false;
1487 if (widthMeasureSpec.Mode != MeasureSpecification.ModeType.Exactly)
1489 if ((AdjustViewSize) && (aspectRatio > 0))
1491 newWidth = newHeight / aspectRatio;
1496 if (widthSpecChanged)
1498 widthMeasureSpec = new MeasureSpecification(new LayoutLength(newWidth), MeasureSpecification.ModeType.Exactly);
1501 if (heightSpecChanged)
1503 heightMeasureSpec = new MeasureSpecification(new LayoutLength(newHeight), MeasureSpecification.ModeType.Exactly);
1506 MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK;
1507 MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK;
1509 SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(newWidth), widthMeasureSpec, childWidthState),
1510 ResolveSizeAndState(new LayoutLength(newHeight), heightMeasureSpec, childHeightState));