/* * Copyright(c) 2019 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ using System.Collections.Generic; using System.ComponentModel; namespace Tizen.NUI.BaseComponents { /// /// AnimatedImageView is a class for displaying Animated-GIF and Image-Array /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] public partial class AnimatedImageView : ImageView { #region Internal #endregion Internal #region Private // Collection of animated-image-sensitive properties. private static readonly List cachedAnimatedImagePropertyKeyList = new List { ImageVisualProperty.BatchSize, ImageVisualProperty.CacheSize, ImageVisualProperty.FrameDelay, ImageVisualProperty.LoopCount, ImageVisualProperty.StopBehavior, }; private List resourceURLs = new List(); #endregion Private #region Constructor, Destructor, Dispose /// /// Construct AnimatedImageView /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] public AnimatedImageView() : base() { ActionPlay = Interop.AnimatedImageView.AnimatedImageVisualActionPlayGet(); ActionPause = Interop.AnimatedImageView.AnimatedImageVisualActionPauseGet(); ActionStop = Interop.AnimatedImageView.AnimatedImageVisualActionStopGet(); } /// /// You can override it to clean-up your own resources /// /// DisposeTypes // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] protected override void Dispose(DisposeTypes type) { if (disposed) { return; } //Release your own unmanaged resources here. //You should not access any managed member here except static instance. //because the execution order of Finalizes is non-deterministic. base.Dispose(type); } #endregion Constructor, Destructor, Dispose #region Property /// /// Image URL list for Image-Array /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] public List URLs { get { return resourceURLs; } } /// /// Defines the batch size for pre-loading images in the Image-Array animation. /// number of images to pre-load before starting to play. Default value: 1. /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] public int BatchSize { get { return (int)GetValue(BatchSizeProperty); } set { SetValue(BatchSizeProperty, value); NotifyPropertyChanged(); } } private int InternalBatchSize { get { int ret = 1; PropertyValue batchSize = GetCachedImageVisualProperty(ImageVisualProperty.BatchSize); batchSize?.Get(out ret); batchSize?.Dispose(); return ret; } set { using PropertyValue setValue = new PropertyValue(value); UpdateImage(ImageVisualProperty.BatchSize, setValue); } } /// /// Defines the cache size for loading images in the Image-Array animation. /// number of images to keep cached ahead during playback. Default value: 1. /// /// /// cacheSize should be >= batchSize. If it isn't, then the cache will automatically be changed to batchSize. /// because of the defaults, it is expected that the application developer tune the batch and cache sizes to their particular use case. /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] public int CacheSize { get { return (int)GetValue(CacheSizeProperty); } set { SetValue(CacheSizeProperty, value); NotifyPropertyChanged(); } } private int InternalCacheSize { get { int ret = 1; PropertyValue cacheSize = GetCachedImageVisualProperty(ImageVisualProperty.CacheSize); cacheSize?.Get(out ret); cacheSize?.Dispose(); return ret; } set { using PropertyValue setValue = new PropertyValue(value); UpdateImage(ImageVisualProperty.CacheSize, setValue); } } /// /// The number of milliseconds between each frame in the Image-Array animation. /// The number of milliseconds between each frame. /// /// /// This is only used when URLs(multiple string) are provided. /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] public int FrameDelay { get { return (int)GetValue(FrameDelayProperty); } set { SetValue(FrameDelayProperty, value); NotifyPropertyChanged(); } } private int InternalFrameDelay { get { int ret = 0; PropertyValue frameDelay = GetCachedImageVisualProperty(ImageVisualProperty.FrameDelay); frameDelay?.Get(out ret); frameDelay?.Dispose(); return ret; } set { using PropertyValue setValue = new PropertyValue(value); UpdateImage(ImageVisualProperty.FrameDelay, setValue); } } /// /// The number of looping. /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] public int LoopCount { get { return (int)GetValue(LoopCountProperty); } set { SetValue(LoopCountProperty, value); NotifyPropertyChanged(); } } private int InternalLoopCount { get { int ret = -1; PropertyValue loopCount = GetCachedImageVisualProperty(ImageVisualProperty.LoopCount); loopCount?.Get(out ret); loopCount?.Dispose(); return ret; } set { using PropertyValue setValue = new PropertyValue(value); UpdateImage(ImageVisualProperty.LoopCount, setValue); } } /// /// Sets or gets the stop behavior. /// [EditorBrowsable(EditorBrowsableState.Never)] public StopBehaviorType StopBehavior { get { return (StopBehaviorType)GetValue(StopBehaviorProperty); } set { SetValue(StopBehaviorProperty, value); NotifyPropertyChanged(); } } private StopBehaviorType InternalStopBehavior { get { int ret = 0; PropertyValue stopBehavior = GetCachedImageVisualProperty(ImageVisualProperty.StopBehavior); stopBehavior?.Get(out ret); stopBehavior?.Dispose(); return (StopBehaviorType)ret; } set { using PropertyValue setValue = new PropertyValue((int)value); UpdateImage(ImageVisualProperty.StopBehavior, setValue); } } /// /// Get the number of total frames /// [EditorBrowsable(EditorBrowsableState.Never)] public int TotalFrame { get { int ret = -1; PropertyMap map = base.Image; if (map != null) { PropertyValue val = map.Find(ImageVisualProperty.TotalFrameNumber); if (val != null) { if (val.Get(out ret)) { return ret; } } } return ret; } } /// /// Set or get the current frame. When setting a specific frame, it is displayed as a still image. /// /// /// Gets the value set by a user. If the setting value is out-ranged, it is reset as a minimum frame or a maximum frame. /// [EditorBrowsable(EditorBrowsableState.Never)] public int CurrentFrame { get { return (int)GetValue(CurrentFrameProperty); } set { SetValue(CurrentFrameProperty, value); NotifyPropertyChanged(); } } private int InternalCurrentFrame { set { // Sync as current properties UpdateImage(); DoAction(ImageView.Property.IMAGE, ActionJumpTo, new PropertyValue(value)); } get { int ret = -1; PropertyMap map = base.Image; if (map != null) { PropertyValue val = map.Find(ImageVisualProperty.CurrentFrameNumber); if (val != null) { if (val.Get(out ret)) { return ret; } } } return ret; } } /// /// Actions property value to Jump to the specified frame. /// This property can be redefined by child class if it use different value. /// [EditorBrowsable(EditorBrowsableState.Never)] protected int ActionJumpTo { get; set; } = Interop.AnimatedImageView.AnimatedImageVisualActionJumpToGet(); #endregion Property #region Method /// /// To make the properies be set. This should be called after the properties are set. /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] public void SetValues() { // This API assume that Animated relative properties setuped forcely. imagePropertyUpdatedFlag = true; // Sync as current properties UpdateImage(); } /// /// Update animated-image-relative properties synchronously. /// After call this API, All image properties updated. /// [EditorBrowsable(EditorBrowsableState.Never)] protected override void UpdateImage() { if (!imagePropertyUpdatedFlag) return; if (resourceURLs != null && resourceURLs.Count != 0) { using (PropertyArray indexPropertyArray = new PropertyArray()) { PropertyArray returnedArr = new PropertyArray(); foreach (var iter in resourceURLs) { using (PropertyValue index = new PropertyValue(iter)) { returnedArr = indexPropertyArray.Add(index); } } returnedArr.Dispose(); using PropertyValue arrayProperty = new PropertyValue(indexPropertyArray); // Trigger the ImageView so that we have something update UpdateImage(ImageVisualProperty.URL, arrayProperty); } } using PropertyValue animatiedImage = new PropertyValue((int)Visual.Type.AnimatedImage); UpdateImage(Visual.Property.Type, animatiedImage); base.UpdateImage(); } /// /// Update NUI cached animated image visual property map by inputed property map. /// And call base.MergeCachedImageVisualProperty() /// /// /// For performance issue, we will collect only "cachedAnimatedImagePropertyKeyList" hold in this class. /// [EditorBrowsable(EditorBrowsableState.Never)] protected override void MergeCachedImageVisualProperty(PropertyMap map) { if (map == null) return; if (cachedImagePropertyMap == null) { cachedImagePropertyMap = new PropertyMap(); } foreach (var key in cachedAnimatedImagePropertyKeyList) { PropertyValue value = map.Find(key); if (value != null) { // Update-or-Insert new value cachedImagePropertyMap[key] = value; } } base.MergeCachedImageVisualProperty(map); } #endregion Method #region Event, Enum, Struct, ETC /// /// Enumeration for what to do when the animation is stopped. /// [EditorBrowsable(EditorBrowsableState.Never)] public enum StopBehaviorType { /// /// When the animation is stopped, the current frame is shown. /// [EditorBrowsable(EditorBrowsableState.Never)] CurrentFrame, /// /// When the animation is stopped, the min frame (first frame) is shown. /// [EditorBrowsable(EditorBrowsableState.Never)] MinimumFrame, /// /// When the animation is stopped, the max frame (last frame) is shown. /// [EditorBrowsable(EditorBrowsableState.Never)] MaximumFrame } #endregion Event, Enum, Struct, ETC } }