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 23namespace OHOS { 24UIDigitalClock::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 37void 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 53void UIDigitalClock::DisplayLeadingZero(bool displayLeadingZero) 54{ 55 leadingZero_ = displayLeadingZero; 56 UpdateClock(false); 57} 58 59void 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 69uint8_t UIDigitalClock::GetOpacity() const 70{ 71 return opaScale_; 72} 73 74void 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 84void 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 93void 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 103void 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 122void UIDigitalClock::RefreshTime() 123{ 124 InitTimeLabels(); 125 for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) { 126 timeLabels_[i]->Invalidate(); 127 } 128} 129 130void 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 187void 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 198void 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 219void UIDigitalClock::SetTimeLabelsPosition() 220{ 221 if (verticalShow_) { 222 SetVertical(); 223 } else { 224 SetHorizontal(); 225 } 226} 227 228void 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 240UIDigitalClock::~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