1 /*
2 * Copyright (c) 2020-2021 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 "components/ui_digital_clock.h"
17 #include <cstdio>
18 #include "components/ui_view_group.h"
19 #include "font/ui_font.h"
20 #include "gfx_utils/graphic_log.h"
21 #include "securec.h"
22
23 namespace OHOS {
UIDigitalClock()24 UIDigitalClock::UIDigitalClock()
25 : timeLabels_{0},
26 displayMode_(DISPLAY_24_HOUR),
27 leadingZero_(true),
28 color_(Color::White()),
29 prevHour_(0),
30 prevMinute_(0),
31 prevSecond_(0),
32 verticalShow_(false)
33 {
34 style_ = &(StyleDefault::GetBackgroundTransparentStyle());
35 }
36
InitTimeLabels()37 void UIDigitalClock::InitTimeLabels()
38 {
39 for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) {
40 if (timeLabels_[i] == nullptr) {
41 timeLabels_[i] = new UILabel;
42 if (timeLabels_[i] == nullptr) {
43 GRAPHIC_LOGE("new UILabel fail");
44 return;
45 }
46 timeLabels_[i]->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT);
47 timeLabels_[i]->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);
48 Add(timeLabels_[i]);
49 }
50 }
51 }
52
DisplayLeadingZero(bool displayLeadingZero)53 void UIDigitalClock::DisplayLeadingZero(bool displayLeadingZero)
54 {
55 leadingZero_ = displayLeadingZero;
56 UpdateClock(false);
57 }
58
SetOpacity(uint8_t opacity)59 void UIDigitalClock::SetOpacity(uint8_t opacity)
60 {
61 opaScale_ = opacity;
62 InitTimeLabels();
63 for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) {
64 timeLabels_[i]->SetStyle(STYLE_TEXT_OPA, opacity);
65 }
66 RefreshTime();
67 }
68
GetOpacity() const69 uint8_t UIDigitalClock::GetOpacity() const
70 {
71 return opaScale_;
72 }
73
SetFontId(uint16_t fontId)74 void UIDigitalClock::SetFontId(uint16_t fontId)
75 {
76 SetStyle(STYLE_TEXT_FONT, fontId);
77 InitTimeLabels();
78 for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) {
79 timeLabels_[i]->SetFontId(fontId);
80 }
81 UpdateClock(false);
82 }
83
SetFont(const char * name,uint8_t size)84 void UIDigitalClock::SetFont(const char* name, uint8_t size)
85 {
86 InitTimeLabels();
87 for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) {
88 timeLabels_[i]->SetFont(name, size);
89 }
90 UpdateClock(false);
91 }
92
SetColor(ColorType color)93 void UIDigitalClock::SetColor(ColorType color)
94 {
95 color_ = color;
96 InitTimeLabels();
97 for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) {
98 timeLabels_[i]->SetStyle(STYLE_TEXT_COLOR, color.full);
99 }
100 RefreshTime();
101 }
102
TimeElementRefresh()103 void UIDigitalClock::TimeElementRefresh()
104 {
105 InitTimeLabels();
106 if (currentHour_ != prevHour_) {
107 prevHour_ = currentHour_;
108 timeLabels_[HOUR_ELEMENT]->Invalidate();
109 }
110
111 if (currentMinute_ != prevMinute_) {
112 prevMinute_ = currentMinute_;
113 timeLabels_[MINUTE_ELEMENT]->Invalidate();
114 }
115
116 if (currentSecond_ != prevSecond_) {
117 prevSecond_ = currentSecond_;
118 timeLabels_[SECOND_ELEMENT]->Invalidate();
119 }
120 }
121
RefreshTime()122 void UIDigitalClock::RefreshTime()
123 {
124 InitTimeLabels();
125 for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) {
126 timeLabels_[i]->Invalidate();
127 }
128 }
129
UpdateClock(bool clockInit)130 void UIDigitalClock::UpdateClock(bool clockInit)
131 {
132 char buf[TIME_ELEMENT_COUNT][BUFFER_SIZE] = {{0}};
133 const char* formatWithColon = leadingZero_ ? "%02d:" : "%d:";
134 const char* formatWithoutColon = leadingZero_ ? "%02d" : "%d";
135 const char* format = verticalShow_ ? formatWithoutColon : formatWithColon;
136 const char* formatForMinute = verticalShow_ ? "%02d" : "%02d:";
137 switch (displayMode_) {
138 case DISPLAY_24_HOUR_NO_SECONDS: {
139 if (sprintf_s(buf[HOUR_ELEMENT], BUFFER_SIZE, format, currentHour_) < 0) {
140 return;
141 }
142 if (sprintf_s(buf[MINUTE_ELEMENT], BUFFER_SIZE, "%02d", currentMinute_) < 0) {
143 return;
144 }
145 break;
146 }
147 case DISPLAY_12_HOUR_NO_SECONDS: {
148 if (sprintf_s(buf[HOUR_ELEMENT], BUFFER_SIZE, format, currentHour_ % HALF_DAY_IN_HOUR) < 0) {
149 return;
150 }
151 if (sprintf_s(buf[MINUTE_ELEMENT], BUFFER_SIZE, "%02d", currentMinute_) < 0) {
152 return;
153 }
154 break;
155 }
156 case DISPLAY_12_HOUR: {
157 if (sprintf_s(buf[HOUR_ELEMENT], BUFFER_SIZE, format, currentHour_ % HALF_DAY_IN_HOUR) < 0) {
158 return;
159 }
160 if (sprintf_s(buf[MINUTE_ELEMENT], BUFFER_SIZE, formatForMinute, currentMinute_) < 0) {
161 return;
162 }
163 if (sprintf_s(buf[SECOND_ELEMENT], BUFFER_SIZE, "%02d", currentSecond_) < 0) {
164 return;
165 }
166 break;
167 }
168 case DISPLAY_24_HOUR: {
169 if (sprintf_s(buf[HOUR_ELEMENT], BUFFER_SIZE, format, currentHour_) < 0) {
170 return;
171 }
172 if (sprintf_s(buf[MINUTE_ELEMENT], BUFFER_SIZE, formatForMinute, currentMinute_) < 0) {
173 return;
174 }
175 if (sprintf_s(buf[SECOND_ELEMENT], BUFFER_SIZE, "%02d", currentSecond_) < 0) {
176 return;
177 }
178 break;
179 }
180 default: {
181 break;
182 }
183 }
184 SetTimeLabels(buf);
185 }
186
SetTimeLabels(const char buf[TIME_ELEMENT_COUNT][BUFFER_SIZE])187 void UIDigitalClock::SetTimeLabels(const char buf[TIME_ELEMENT_COUNT][BUFFER_SIZE])
188 {
189 InitTimeLabels();
190 for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) {
191 timeLabels_[i]->SetText(buf[i]);
192 }
193
194 SetTimeLabelsPosition();
195 TimeElementRefresh();
196 }
197
SetHorizontal()198 void UIDigitalClock::SetHorizontal()
199 {
200 InitTimeLabels();
201 uint16_t totalWidth = timeLabels_[HOUR_ELEMENT]->GetWidth() + timeLabels_[MINUTE_ELEMENT]->GetWidth() +
202 timeLabels_[SECOND_ELEMENT]->GetWidth();
203 UITextLanguageAlignment align = timeLabels_[HOUR_ELEMENT]->GetHorAlign();
204 int16_t x = 0;
205 Rect rect = GetContentRect();
206 if (align == TEXT_ALIGNMENT_CENTER) {
207 x = (rect.GetWidth() >> 1) - (totalWidth >> 1);
208 } else if (align == TEXT_ALIGNMENT_RIGHT) {
209 x = rect.GetRight() - totalWidth;
210 }
211 timeLabels_[HOUR_ELEMENT]->SetPosition(x, 0);
212 int16_t width = timeLabels_[HOUR_ELEMENT]->GetWidth();
213 for (uint8_t i = 1; i < TIME_ELEMENT_COUNT; i++) {
214 timeLabels_[i]->SetPosition(x + width, 0);
215 width += timeLabels_[i]->GetWidth();
216 }
217 }
218
SetTimeLabelsPosition()219 void UIDigitalClock::SetTimeLabelsPosition()
220 {
221 if (verticalShow_) {
222 SetVertical();
223 } else {
224 SetHorizontal();
225 }
226 }
227
SetVertical()228 void UIDigitalClock::SetVertical()
229 {
230 InitTimeLabels();
231 int16_t fontHeight = timeLabels_[HOUR_ELEMENT]->GetHeight();
232 timeLabels_[HOUR_ELEMENT]->SetPosition(0, 0);
233 int16_t y = fontHeight;
234 for (uint8_t i = 1; i < TIME_ELEMENT_COUNT; i++) {
235 timeLabels_[i]->SetPosition(0, y);
236 y += fontHeight;
237 }
238 }
239
~UIDigitalClock()240 UIDigitalClock::~UIDigitalClock()
241 {
242 for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) {
243 if (timeLabels_[i] != nullptr) {
244 Remove(timeLabels_[i]);
245 delete timeLabels_[i];
246 timeLabels_[i] = nullptr;
247 }
248 }
249 }
250 } // namespace OHOS
251