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 <string> 19 20 #include "base/i18n/localization.h" 21 #include "core/components/stack/stack_element.h" 22 #include "core/components/text/render_text.h" 23 #include "core/components/texttimer/texttimer_component.h" 24 25 namespace OHOS::Ace { RenderTextTimer()26RenderTextTimer::RenderTextTimer() 27 { 28 textComponent_ = AceType::MakeRefPtr<TextComponent>(std::string("")); 29 renderText_ = AceType::DynamicCast<RenderText>(RenderText::Create()); 30 AddChild(renderText_); 31 } 32 ~RenderTextTimer()33RenderTextTimer::~RenderTextTimer() 34 { 35 if (scheduler_ && scheduler_->IsActive()) { 36 scheduler_->Stop(); 37 } 38 } 39 Update(const RefPtr<Component> & component)40void RenderTextTimer::Update(const RefPtr<Component>& component) 41 { 42 auto timerComponent = AceType::DynamicCast<TextTimerComponent>(component); 43 if (!timerComponent) { 44 LOGE("input timerComponent is incorrect type or null."); 45 return; 46 } 47 48 inputCount_ = timerComponent->GetInputCount(); 49 isCountDown_ = timerComponent->GetIsCountDown(); 50 format_ = timerComponent->GetFormat(); 51 52 const auto context = context_.Upgrade(); 53 if (context && context->GetIsDeclarative()) { 54 if (timerComponent->GetOnTimer()) { 55 onTimer_ = *timerComponent->GetOnTimer(); 56 } 57 } 58 59 const auto& timerController = timerComponent->GetTextTimerController(); 60 if (timerController) { 61 auto weak = AceType::WeakClaim(this); 62 timerController->OnStart([weak]() { 63 auto timerRender = weak.Upgrade(); 64 if (timerRender) { 65 timerRender->HandleStart(); 66 } 67 }); 68 timerController->OnPause([weak]() { 69 auto timerRender = weak.Upgrade(); 70 if (timerRender) { 71 timerRender->HandlePause(); 72 } 73 }); 74 timerController->OnReset([weak]() { 75 auto timerRender = weak.Upgrade(); 76 if (timerRender) { 77 timerRender->HandleReset(); 78 } 79 }); 80 } 81 82 auto weak = AceType::WeakClaim(this); 83 if (!scheduler_) { 84 auto&& callback = [weak](uint64_t duration) { 85 auto timer = weak.Upgrade(); 86 if (timer) { 87 timer->Tick(duration); 88 } else { 89 LOGW("empty timer, skip tick callback."); 90 } 91 }; 92 scheduler_ = SchedulerBuilder::Build(callback, context); 93 textComponent_->SetTextStyle(timerComponent->GetTextStyle()); 94 UpdateValue(isCountDown_ ? inputCount_ : 0); 95 } else { 96 HandleReset(); 97 } 98 99 MarkNeedRender(); 100 } 101 PerformLayout()102void RenderTextTimer::PerformLayout() 103 { 104 Size layoutSize; 105 const auto& children = GetChildren(); 106 if (!children.empty()) { 107 auto child = children.front(); 108 child->Layout(GetLayoutParam()); 109 child->SetPosition(Offset::Zero()); 110 layoutSize = child->GetLayoutSize(); 111 } 112 SetLayoutSize(layoutSize); 113 } 114 UpdateValue(uint32_t elapsedTime)115void RenderTextTimer::UpdateValue(uint32_t elapsedTime) 116 { 117 std::string timerText = Localization::GetInstance()->FormatDuration(elapsedTime, format_); 118 119 if (!textComponent_) { 120 LOGE("(RenderTextTimer::UpdateValue)texttimer component is null."); 121 return; 122 } 123 124 if (textComponent_->GetData() == timerText) { 125 return; // needless to update 126 } 127 128 textComponent_->SetData(timerText); 129 if (!renderText_) { 130 LOGE("(RenderTextTimer::UpdateValue)render texttimer is null."); 131 return; 132 } 133 renderText_->Attach(GetContext()); 134 renderText_->Update(textComponent_); 135 MarkNeedRender(); 136 } 137 Tick(uint64_t duration)138void RenderTextTimer::Tick(uint64_t duration) 139 { 140 elapsedTime_ += duration; 141 142 if (onTimer_) { 143 onTimer_(GetMilliseconds(), elapsedTime_); 144 } 145 146 double tmp_value = static_cast<double>(elapsedTime_); 147 if (isCountDown_) { 148 tmp_value = (inputCount_ >= elapsedTime_) ? (inputCount_ - elapsedTime_) : 0; 149 } 150 151 if (isCountDown_ && tmp_value <= 0) { 152 UpdateValue(0); 153 HandlePause(); 154 return; 155 } 156 157 UpdateValue(static_cast<uint32_t>(tmp_value)); 158 } 159 HandleStart()160void RenderTextTimer::HandleStart() 161 { 162 if (scheduler_ && !scheduler_->IsActive()) { 163 scheduler_->Start(); 164 } 165 } 166 HandlePause()167void RenderTextTimer::HandlePause() 168 { 169 if (scheduler_ && scheduler_->IsActive()) { 170 scheduler_->Stop(); 171 } 172 } 173 HandleReset()174void RenderTextTimer::HandleReset() 175 { 176 if (scheduler_ && scheduler_->IsActive()) { 177 scheduler_->Stop(); 178 } 179 elapsedTime_ = 0; 180 UpdateValue(isCountDown_ ? inputCount_ : 0); 181 } 182 } // namespace OHOS::Ace