* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "components/ui_digital_clock.h"
#include <cstdio>
#include "components/ui_view_group.h"
#include "font/ui_font.h"
#include "gfx_utils/graphic_log.h"
#include "securec.h"
namespace OHOS {
UIDigitalClock::UIDigitalClock()
: timeLabels_{0},
displayMode_(DISPLAY_24_HOUR),
leadingZero_(true),
color_(Color::White()),
prevHour_(0),
prevMinute_(0),
prevSecond_(0),
verticalShow_(false)
{
style_ = &(StyleDefault::GetBackgroundTransparentStyle());
}
void UIDigitalClock::InitTimeLabels()
{
for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) {
if (timeLabels_[i] == nullptr) {
timeLabels_[i] = new UILabel;
if (timeLabels_[i] == nullptr) {
GRAPHIC_LOGE("new UILabel fail");
return;
}
timeLabels_[i]->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT);
timeLabels_[i]->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);
Add(timeLabels_[i]);
}
}
}
void UIDigitalClock::DisplayLeadingZero(bool displayLeadingZero)
{
leadingZero_ = displayLeadingZero;
UpdateClock(false);
}
void UIDigitalClock::SetOpacity(uint8_t opacity)
{
opaScale_ = opacity;
InitTimeLabels();
for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) {
timeLabels_[i]->SetStyle(STYLE_TEXT_OPA, opacity);
}
RefreshTime();
}
uint8_t UIDigitalClock::GetOpacity() const
{
return opaScale_;
}
void UIDigitalClock::SetFontId(uint16_t fontId)
{
SetStyle(STYLE_TEXT_FONT, fontId);
InitTimeLabels();
for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) {
timeLabels_[i]->SetFontId(fontId);
}
UpdateClock(false);
}
void UIDigitalClock::SetFont(const char* name, uint8_t size)
{
InitTimeLabels();
for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) {
timeLabels_[i]->SetFont(name, size);
}
UpdateClock(false);
}
void UIDigitalClock::SetColor(ColorType color)
{
color_ = color;
InitTimeLabels();
for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) {
timeLabels_[i]->SetStyle(STYLE_TEXT_COLOR, color.full);
}
RefreshTime();
}
void UIDigitalClock::TimeElementRefresh()
{
InitTimeLabels();
if (currentHour_ != prevHour_) {
prevHour_ = currentHour_;
timeLabels_[HOUR_ELEMENT]->Invalidate();
}
if (currentMinute_ != prevMinute_) {
prevMinute_ = currentMinute_;
timeLabels_[MINUTE_ELEMENT]->Invalidate();
}
if (currentSecond_ != prevSecond_) {
prevSecond_ = currentSecond_;
timeLabels_[SECOND_ELEMENT]->Invalidate();
}
}
void UIDigitalClock::RefreshTime()
{
InitTimeLabels();
for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) {
timeLabels_[i]->Invalidate();
}
}
void UIDigitalClock::UpdateClock(bool clockInit)
{
char buf[TIME_ELEMENT_COUNT][BUFFER_SIZE] = {{0}};
const char* formatWithColon = leadingZero_ ? "%02d:" : "%d:";
const char* formatWithoutColon = leadingZero_ ? "%02d" : "%d";
const char* format = verticalShow_ ? formatWithoutColon : formatWithColon;
const char* formatForMinute = verticalShow_ ? "%02d" : "%02d:";
switch (displayMode_) {
case DISPLAY_24_HOUR_NO_SECONDS: {
if (sprintf_s(buf[HOUR_ELEMENT], BUFFER_SIZE, format, currentHour_) < 0) {
return;
}
if (sprintf_s(buf[MINUTE_ELEMENT], BUFFER_SIZE, "%02d", currentMinute_) < 0) {
return;
}
break;
}
case DISPLAY_12_HOUR_NO_SECONDS: {
if (sprintf_s(buf[HOUR_ELEMENT], BUFFER_SIZE, format, currentHour_ % HALF_DAY_IN_HOUR) < 0) {
return;
}
if (sprintf_s(buf[MINUTE_ELEMENT], BUFFER_SIZE, "%02d", currentMinute_) < 0) {
return;
}
break;
}
case DISPLAY_12_HOUR: {
if (sprintf_s(buf[HOUR_ELEMENT], BUFFER_SIZE, format, currentHour_ % HALF_DAY_IN_HOUR) < 0) {
return;
}
if (sprintf_s(buf[MINUTE_ELEMENT], BUFFER_SIZE, formatForMinute, currentMinute_) < 0) {
return;
}
if (sprintf_s(buf[SECOND_ELEMENT], BUFFER_SIZE, "%02d", currentSecond_) < 0) {
return;
}
break;
}
case DISPLAY_24_HOUR: {
if (sprintf_s(buf[HOUR_ELEMENT], BUFFER_SIZE, format, currentHour_) < 0) {
return;
}
if (sprintf_s(buf[MINUTE_ELEMENT], BUFFER_SIZE, formatForMinute, currentMinute_) < 0) {
return;
}
if (sprintf_s(buf[SECOND_ELEMENT], BUFFER_SIZE, "%02d", currentSecond_) < 0) {
return;
}
break;
}
default: {
break;
}
}
SetTimeLabels(buf);
}
void UIDigitalClock::SetTimeLabels(const char buf[TIME_ELEMENT_COUNT][BUFFER_SIZE])
{
InitTimeLabels();
for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) {
timeLabels_[i]->SetText(buf[i]);
}
SetTimeLabelsPosition();
TimeElementRefresh();
}
void UIDigitalClock::SetHorizontal()
{
InitTimeLabels();
uint16_t totalWidth = timeLabels_[HOUR_ELEMENT]->GetWidth() + timeLabels_[MINUTE_ELEMENT]->GetWidth() +
timeLabels_[SECOND_ELEMENT]->GetWidth();
UITextLanguageAlignment align = timeLabels_[HOUR_ELEMENT]->GetHorAlign();
int16_t x = 0;
Rect rect = GetContentRect();
if (align == TEXT_ALIGNMENT_CENTER) {
x = (rect.GetWidth() >> 1) - (totalWidth >> 1);
} else if (align == TEXT_ALIGNMENT_RIGHT) {
x = rect.GetRight() - totalWidth;
}
timeLabels_[HOUR_ELEMENT]->SetPosition(x, 0);
int16_t width = timeLabels_[HOUR_ELEMENT]->GetWidth();
for (uint8_t i = 1; i < TIME_ELEMENT_COUNT; i++) {
timeLabels_[i]->SetPosition(x + width, 0);
width += timeLabels_[i]->GetWidth();
}
}
void UIDigitalClock::SetTimeLabelsPosition()
{
if (verticalShow_) {
SetVertical();
} else {
SetHorizontal();
}
}
void UIDigitalClock::SetVertical()
{
InitTimeLabels();
int16_t fontHeight = timeLabels_[HOUR_ELEMENT]->GetHeight();
timeLabels_[HOUR_ELEMENT]->SetPosition(0, 0);
int16_t y = fontHeight;
for (uint8_t i = 1; i < TIME_ELEMENT_COUNT; i++) {
timeLabels_[i]->SetPosition(0, y);
y += fontHeight;
}
}
UIDigitalClock::~UIDigitalClock()
{
for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) {
if (timeLabels_[i] != nullptr) {
Remove(timeLabels_[i]);
delete timeLabels_[i];
timeLabels_[i] = nullptr;
}
}
}
}