* Copyright (c) 2020-2021 Huawei Device 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.
*/
#include "components/ui_image_animator.h"
namespace OHOS {
UIImageAnimatorView::UIImageAnimatorView()
: imageSrc_(nullptr),
imageNum_(0),
tickOfUpdate_(1),
timeOfUpdate_(DEFAULT_TASK_PERIOD),
timeOfPause_(0),
tickOfPause_(0),
repeatTimes_(1),
imageAnimator_(&imageAnimatorCallback_, this, 0, true),
listener_(nullptr),
reverse_(false),
repeat_(true),
sizeFixed_(false),
fillMode_(true),
isPlayImageByTimestamp_(false)
{
}
UIImageAnimatorView::~UIImageAnimatorView() {}
void UIImageAnimatorView::ImageAnimatorCallback::Callback(UIView* view)
{
if (view == nullptr) {
return;
}
UIImageAnimatorView* imageAnimatorView = static_cast<UIImageAnimatorView*>(view);
if (imageAnimatorView->IsPlayImageByTimestamp()) {
PlayImageByTimestamp(imageAnimatorView);
return;
}
imageSrc_ = imageAnimatorView->GetImageAnimatorSrc();
imageNum_ = imageAnimatorView->GetImageAnimatorImageNum();
if ((imageSrc_ == nullptr) || (imageNum_ == 0) || (imageAnimatorView->tickOfUpdate_ == 0)) {
return;
}
if (!imageAnimatorView->IsRepeat() && (repeat_ == imageAnimatorView->GetRepeatTimes())) {
imageAnimatorView->Stop();
return;
}
tickNum_++;
if (loop_ != imageNum_) {
if (tickNum_ < imageAnimatorView->tickOfUpdate_) {
return;
}
} else {
if (imageAnimatorView->tickOfPause_ != 0) {
if (tickNum_ < imageAnimatorView->tickOfPause_) {
return;
}
} else {
if (tickNum_ < imageAnimatorView->tickOfUpdate_) {
return;
}
}
repeat_++;
loop_ = 0;
if (!imageAnimatorView->IsRepeat() && (repeat_ == imageAnimatorView->GetRepeatTimes())) {
imageAnimatorView->Stop();
return;
}
}
imageAnimatorView->UpdateImage(drawingImage_, loop_);
tickNum_ = 0;
}
void UIImageAnimatorView::ImageAnimatorCallback::PlayImageByTimestamp(UIImageAnimatorView* imageAnimatorView)
{
imageSrc_ = imageAnimatorView->GetImageAnimatorSrc();
imageNum_ = imageAnimatorView->GetImageAnimatorImageNum();
if ((imageSrc_ == nullptr) || (imageNum_ == 0) || (imageAnimatorView->GetTimeOfUpdate() == 0)) {
return;
}
if (loop_ >= imageNum_) {
repeat_++;
loop_ = 0;
}
if (!imageAnimatorView->IsRepeat() && (repeat_ == imageAnimatorView->GetRepeatTimes())) {
imageAnimatorView->Stop();
return;
}
uint32_t runTime = imageAnimatorView->GetRunTime();
uint16_t pauseTime = imageAnimatorView->GetTimeOfPause();
uint16_t playImageTime = pauseTime > 0 ? pauseTime : imageAnimatorView->GetTimeOfUpdate();
if ((totalRunTime_ != 0) && ((runTime - totalRunTime_) < playImageTime)) {
return;
}
totalRunTime_ = runTime;
imageAnimatorView->UpdateImage(drawingImage_, loop_);
}
void UIImageAnimatorView::UpdateImage(uint8_t& drawingImage, uint8_t& loop)
{
Invalidate();
drawingImage = reverse_ ? (imageNum_ - loop - 1) : loop;
if (drawingImage >= imageNum_) {
return;
}
ImageAnimatorInfo* imageAnimatorInfo = &(imageSrc_[drawingImage]);
if (imageAnimatorInfo->imageType == IMG_SRC_FILE_PATH) {
SetSrc(imageAnimatorInfo->imagePath);
} else if (imageAnimatorInfo->imageType == IMG_SRC_IMAGE_INFO) {
SetSrc(imageAnimatorInfo->imageInfo);
}
if (!sizeFixed_) {
SetPosition(imageAnimatorInfo->pos.x, imageAnimatorInfo->pos.y);
SetWidth(imageAnimatorInfo->width);
SetHeight(imageAnimatorInfo->height);
}
Invalidate();
loop++;
}
void UIImageAnimatorView::SetImageAnimatorSrc(const ImageAnimatorInfo imageAnimatorInfoSrc[], uint8_t imageNum)
{
SetImageAnimatorSrc(imageAnimatorInfoSrc, imageNum, timeOfUpdate_);
}
void UIImageAnimatorView::SetImageAnimatorSrc(const ImageAnimatorInfo imageAnimatorInfoSrc[],
uint8_t imageNum,
uint16_t timeOfUpdate)
{
imageSrc_ = const_cast<ImageAnimatorInfo*>(imageAnimatorInfoSrc);
imageNum_ = imageNum;
timeOfUpdate_ = timeOfUpdate;
tickOfUpdate_ = GetTickByTime(timeOfUpdate);
return;
}
const ImageAnimatorInfo* UIImageAnimatorView::GetImageAnimatorSrc() const
{
return imageSrc_;
}
uint8_t UIImageAnimatorView::GetImageAnimatorImageNum() const
{
return imageNum_;
}
void UIImageAnimatorView::SetTimeOfUpdate(uint16_t timeOfUpdate)
{
timeOfUpdate_ = timeOfUpdate;
tickOfUpdate_ = GetTickByTime(timeOfUpdate);
}
uint16_t UIImageAnimatorView::GetTimeOfUpdate() const
{
return timeOfUpdate_;
}
void UIImageAnimatorView::SetTimeOfPause(uint16_t timeOfPause)
{
timeOfPause_ = timeOfPause;
tickOfPause_ = GetTickByTime(timeOfPause);
}
uint16_t UIImageAnimatorView::GetTimeOfPause() const
{
return timeOfPause_;
}
void UIImageAnimatorView::Start()
{
Reset(false);
imageAnimator_.Start();
}
void UIImageAnimatorView::Reset(bool fillMode)
{
if ((imageSrc_ == nullptr) || (imageNum_ == 0)) {
return;
}
Invalidate();
uint8_t drawingImage;
if (fillMode) {
drawingImage = reverse_ ? 0 : (imageNum_ - 1);
} else {
drawingImage = reverse_ ? (imageNum_ - 1) : 0;
}
ImageAnimatorInfo* imageAnimatorInfo = &(imageSrc_[drawingImage]);
if (imageAnimatorInfo->imageType == IMG_SRC_FILE_PATH) {
SetSrc(imageAnimatorInfo->imagePath);
} else if (imageAnimatorInfo->imageType == IMG_SRC_IMAGE_INFO) {
SetSrc(imageAnimatorInfo->imageInfo);
}
if (!sizeFixed_) {
SetPosition(imageAnimatorInfo->pos.x, imageAnimatorInfo->pos.y);
SetWidth(imageAnimatorInfo->width);
SetHeight(imageAnimatorInfo->height);
}
Invalidate();
imageAnimatorCallback_.Reset();
}
void UIImageAnimatorView::Stop()
{
if (imageAnimator_.GetState() == Animator::STOP) {
return;
}
imageAnimator_.Stop();
Reset(fillMode_);
if (listener_ != nullptr) {
listener_->OnAnimatorStop(*this);
}
}
void UIImageAnimatorView::Pause()
{
imageAnimator_.Pause();
}
void UIImageAnimatorView::Resume()
{
imageAnimator_.Resume();
}
uint8_t UIImageAnimatorView::GetTickByTime(uint16_t time) const
{
uint8_t tick;
if ((time > 0) && (time <= DEFAULT_TASK_PERIOD)) {
tick = 1;
} else {
tick = time / DEFAULT_TASK_PERIOD;
}
return tick;
}
}