1 /*
2  * Copyright (c) 2021-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/text_clock/render_text_clock.h"
17 #include "core/components/text_clock/text_clock_controller.h"
18 
19 #include <chrono>
20 #include <string>
21 #include <sys/time.h>
22 
23 #include "base/utils/string_utils.h"
24 #include "core/components/image/image_component.h"
25 #include "core/event/ace_event_helper.h"
26 
27 namespace OHOS::Ace {
28 namespace {
29 constexpr int32_t BASE_YEAR = 1900;
30 }
31 
RenderTextClock()32 RenderTextClock::RenderTextClock()
33 {
34     timeTextComponent_ = AceType::MakeRefPtr<TextComponent>(std::string(""));
35     renderTimeText_ = AceType::DynamicCast<RenderText>(RenderText::Create());
36     AddChild(renderTimeText_);
37 }
38 
Update(const RefPtr<Component> & component)39 void RenderTextClock::Update(const RefPtr<Component>& component)
40 {
41     textClockComponent_ = AceType::DynamicCast<TextClockComponent>(component);
42     if (textClockComponent_ == nullptr) {
43         LOGE("textClockComponent is null!");
44         return;
45     }
46     format_ = textClockComponent_->GetFormat();
47     textStyle_ = textClockComponent_->GetTextStyle();
48     hoursWest_ = textClockComponent_->GetHoursWest();
49     if (textClockComponent_->GetOnDateChange()) {
50         onDateChange = *textClockComponent_->GetOnDateChange();
51     }
52     UpdateTimeText();
53     auto textClockController = textClockComponent_->GetTextClockController();
54     if (textClockController) {
55         textClockController->OnStart([wp = WeakClaim(this)]() {
56             auto textClock = wp.Upgrade();
57             if (textClock) {
58                 textClock->isStart_ = true;
59                 textClock->MarkNeedLayout();
60             }
61         });
62         textClockController->OnStop([wp = WeakClaim(this)]() {
63             auto textClock = wp.Upgrade();
64             if (textClock) {
65                 textClock->isStart_ = false;
66                 textClock->MarkNeedLayout();
67             }
68         });
69     }
70     timeCallback_ = ([wp = WeakClaim(this)]() {
71         auto renderTextClock = wp.Upgrade();
72         if (renderTextClock) {
73             renderTextClock->UpdateTimeText();
74         } else {
75             LOGE("renderTextClock is empty");
76         }
77     });
78 }
79 
UpdateTimeText()80 void RenderTextClock::UpdateTimeText()
81 {
82     currentTimeText_ = GetFormatDateTime(format_);
83     timeTextComponent_->SetData(currentTimeText_);
84     timeTextComponent_->SetTextStyle(textStyle_);
85     renderTimeText_->Attach(GetContext());
86     renderTimeText_->Update(timeTextComponent_);
87 }
88 
UpdateTimeTextCallBack()89 void RenderTextClock::UpdateTimeTextCallBack()
90 {
91     if (timeCallback_) {
92         timeCallback_();
93     }
94     if (!onDateChange) {
95         LOGE("func is Null");
96         return;
97     } else {
98         currentMillisecond_ = GetMilliseconds();
99         onDateChange(std::to_string(currentMillisecond_));
100     }
101 }
102 
PerformLayout()103 void RenderTextClock::PerformLayout()
104 {
105     if (GetChildren().size() != 1) {
106         return;
107     }
108     const auto& timeTextChild = GetChildren().front();
109     LayoutParam layoutParam = GetLayoutParam();
110     if (!timeTextChild) {
111         return;
112     }
113     timeTextChild->Layout(layoutParam);
114     SetLayoutSize(GetLayoutParam().Constrain(timeTextChild->GetLayoutSize()));
115 }
116 
GetDateTime() const117 DateTime RenderTextClock::GetDateTime() const
118 {
119     auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
120     auto local = std::localtime(&now);
121     if (local == nullptr) {
122         LOGE("Get localtime failed.");
123         return DateTime();
124     }
125     // This is for i18n date time
126     DateTime dateTime;
127     dateTime.year = static_cast<uint32_t>(local->tm_year + BASE_YEAR);
128     dateTime.month = static_cast<uint32_t>(local->tm_mon);
129     dateTime.day = static_cast<uint32_t>(local->tm_mday);
130     TimeOfNow timeOfNow = GetTimeOfNow(hoursWest_);
131     dateTime.hour = static_cast<uint32_t>(timeOfNow.hour24_);
132     dateTime.minute = static_cast<uint32_t>(timeOfNow.minute_);
133     dateTime.second = static_cast<uint32_t>(timeOfNow.second_);
134     return dateTime;
135 }
136 
GetFormatDateTime(const std::string & format) const137 std::string RenderTextClock::GetFormatDateTime(const std::string& format) const
138 {
139     DateTime dateTime = GetDateTime();
140     std::string time = Localization::GetInstance()->FormatDateTime(dateTime, format);
141     return time;
142 }
143 } // namespace OHOS::Ace