1 /* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "core/components/texttimer/render_texttimer.h" 17 18 #include "base/i18n/localization.h" 19 #include "core/components/texttimer/texttimer_component.h" 20 21 namespace OHOS::Ace { RenderTextTimer()22RenderTextTimer::RenderTextTimer() 23 { 24 textComponent_ = AceType::MakeRefPtr<TextComponent>(std::string("")); 25 renderText_ = AceType::DynamicCast<RenderText>(RenderText::Create()); 26 AddChild(renderText_); 27 } 28 ~RenderTextTimer()29RenderTextTimer::~RenderTextTimer() 30 { 31 if (scheduler_ && scheduler_->IsActive()) { 32 scheduler_->Stop(); 33 } 34 } 35 Update(const RefPtr<Component> & component)36void RenderTextTimer::Update(const RefPtr<Component>& component) 37 { 38 auto timerComponent = AceType::DynamicCast<TextTimerComponent>(component); 39 if (!timerComponent) { 40 LOGE("input timerComponent is incorrect type or null."); 41 return; 42 } 43 44 inputCount_ = timerComponent->GetInputCount(); 45 isCountDown_ = timerComponent->GetIsCountDown(); 46 format_ = timerComponent->GetFormat(); 47 48 const auto context = context_.Upgrade(); 49 if (context && context->GetIsDeclarative()) { 50 if (timerComponent->GetOnTimer()) { 51 onTimer_ = *timerComponent->GetOnTimer(); 52 } 53 } 54 55 const auto& timerController = timerComponent->GetTextTimerController(); 56 if (timerController) { 57 auto weak = AceType::WeakClaim(this); 58 timerController->OnStart([weak]() { 59 auto timerRender = weak.Upgrade(); 60 if (timerRender) { 61 timerRender->HandleStart(); 62 } 63 }); 64 timerController->OnPause([weak]() { 65 auto timerRender = weak.Upgrade(); 66 if (timerRender) { 67 timerRender->HandlePause(); 68 } 69 }); 70 timerController->OnReset([weak]() { 71 auto timerRender = weak.Upgrade(); 72 if (timerRender) { 73 timerRender->HandleReset(); 74 } 75 }); 76 } 77 78 auto weak = AceType::WeakClaim(this); 79 if (!scheduler_) { 80 auto&& callback = [weak](uint64_t duration) { 81 auto timer = weak.Upgrade(); 82 if (timer) { 83 timer->Tick(duration); 84 } else { 85 LOGW("empty timer, skip tick callback."); 86 } 87 }; 88 scheduler_ = SchedulerBuilder::Build(callback, context); 89 textComponent_->SetTextStyle(timerComponent->GetTextStyle()); 90 UpdateValue(isCountDown_ ? inputCount_ : 0); 91 } else { 92 HandleReset(); 93 } 94 95 MarkNeedRender(); 96 } 97 PerformLayout()98void RenderTextTimer::PerformLayout() 99 { 100 Size layoutSize; 101 const auto& children = GetChildren(); 102 if (!children.empty()) { 103 auto child = children.front(); 104 child->Layout(GetLayoutParam()); 105 child->SetPosition(Offset::Zero()); 106 layoutSize = child->GetLayoutSize(); 107 } 108 SetLayoutSize(layoutSize); 109 } 110 UpdateValue(uint32_t elapsedTime)111void RenderTextTimer::UpdateValue(uint32_t elapsedTime) 112 { 113 std::string timerText = Localization::GetInstance()->FormatDuration(elapsedTime, format_); 114 115 if (!textComponent_) { 116 LOGE("(RenderTextTimer::UpdateValue)texttimer component is null."); 117 return; 118 } 119 120 if (textComponent_->GetData() == timerText) { 121 return; // needless to update 122 } 123 124 textComponent_->SetData(timerText); 125 if (!renderText_) { 126 LOGE("(RenderTextTimer::UpdateValue)render texttimer is null."); 127 return; 128 } 129 renderText_->Attach(GetContext()); 130 renderText_->Update(textComponent_); 131 MarkNeedRender(); 132 } 133 Tick(uint64_t duration)134void RenderTextTimer::Tick(uint64_t duration) 135 { 136 elapsedTime_ += duration; 137 138 if (onTimer_) { 139 onTimer_(GetMilliseconds(), elapsedTime_); 140 } 141 142 double tmp_value = static_cast<double>(elapsedTime_); 143 if (isCountDown_) { 144 tmp_value = (inputCount_ >= elapsedTime_) ? (inputCount_ - elapsedTime_) : 0; 145 } 146 147 if (isCountDown_ && tmp_value <= 0) { 148 UpdateValue(0); 149 HandlePause(); 150 return; 151 } 152 153 UpdateValue(static_cast<uint32_t>(tmp_value)); 154 } 155 HandleStart()156void RenderTextTimer::HandleStart() 157 { 158 if (scheduler_ && !scheduler_->IsActive()) { 159 scheduler_->Start(); 160 } 161 } 162 HandlePause()163void RenderTextTimer::HandlePause() 164 { 165 if (scheduler_ && scheduler_->IsActive()) { 166 scheduler_->Stop(); 167 } 168 } 169 HandleReset()170void RenderTextTimer::HandleReset() 171 { 172 if (scheduler_ && scheduler_->IsActive()) { 173 scheduler_->Stop(); 174 } 175 elapsedTime_ = 0; 176 UpdateValue(isCountDown_ ? inputCount_ : 0); 177 } 178 } // namespace OHOS::Ace