/*
* 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
}
}