mcu_hi3321_watch/tjd/ui/app/main/TjdUiAppMainPageTool.cpp
2025-05-26 20:15:20 +08:00

412 lines
15 KiB
C++

/*----------------------------------------------------------------------------
* Copyright (c) TJD Technologies Co., Ltd. 2024. All rights reserved.
*
* Description: TjdUiAppMainPageTool.cpp
*
* Author: luziquan@ss-tjd.com
*
* Create: 2024-12-27
*--------------------------------------------------------------------------*/
#include "TjdUiAppMainPageTool.h"
#include "NativeAbility.h"
#include "TjdUiAppIds.h"
#include "TjdUiImageIds.h"
#include "TjdUiMultiLanguageExt.h"
#include "common/image_cache_manager.h"
#include "common/screen.h"
#include "gfx_utils/mem_check.h"
#include "rtc_api.h"
#include "sql_alarm.h"
#include "sys_config.h"
#include <iomanip>
#include <sstream>
#define ENABLE_PRINT_INFO 1
#if ENABLE_PRINT_INFO
#define static_print_info(...) sys_ui_log_i(__VA_ARGS__) // 一般信息打印宏控制
#define static_print_warn(...) sys_ui_log_w(__VA_ARGS__) // 警告信息打印一般常开
#define static_print_error(...) sys_ui_log_e(__VA_ARGS__) // 错误信息打印一般常开
#define static_print_debug(...) sys_ui_log_d(__VA_ARGS__)
#else
#define static_print_info(...)
#define static_print_warn(...)
#define static_print_error(...)
#define static_print_debug(...)
#endif
namespace TJD {
constexpr const char *CALCULATOR_VIEW_ID = "calculator";
constexpr const char *STOPWATCH_VIEW_ID = "stopwatch";
constexpr const char *TIMER_VIEW_ID = "timer";
constexpr const char *ALARM_CLOCK_VIEW_ID = "alarmClock";
#define MAIN_TOOL_IMAGE_BIN_PATH TJD_IMAGE_PATH "img_main_tool.bin"
#pragma region 日历界面
class TjdUiAppMainPageTool::CalendarView : public OHOS::UIViewGroup
{
public:
CalendarView(struct rtc_time curDate);
virtual ~CalendarView() { RemoveAll(); }
private:
void CalculateWeekDays(const struct rtc_time &curDate, int weekDay[7]);
bool IsLeapYear(int year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); }
int GetDaysInMonth(int year, int month);
OHOS::UILabel weekText_[7];
};
TjdUiAppMainPageTool::CalendarView::CalendarView(struct rtc_time curDate)
{
SetPosition(86, 75, 296, 36);
int weekDay[7] = {};
CalculateWeekDays(curDate, weekDay);
int numberOfLabels = 7;
int labelWidth = GetHeight();
int labelHeight = GetHeight();
int totalLabelWidth = labelWidth * numberOfLabels;
int interval = (GetWidth() - totalLabelWidth) / (numberOfLabels - 1);
for (uint8_t i = 0; i < numberOfLabels; ++i) {
if (i == 0 || i == numberOfLabels - 1) {
weekText_[i].SetStyle(OHOS::STYLE_TEXT_OPA, OHOS::OPA_OPAQUE * 0.5);
}
std::stringstream ss;
ss << std::setw(2) << std::setfill('0') << weekDay[i];
weekText_[i].SetFont(TJD_DIN_MEDIUM_FONT_FILENAME, 24);
weekText_[i].SetText(ss.str().c_str());
weekText_[i].SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ELLIPSIS);
weekText_[i].SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
int posX = i * (labelWidth + interval);
weekText_[i].SetPosition(posX, 0, labelWidth, labelHeight);
if (weekDay[i] == curDate.tm_mday) {
weekText_[i].SetStyle(OHOS::STYLE_BACKGROUND_OPA, OHOS::OPA_OPAQUE);
weekText_[i].SetStyle(OHOS::STYLE_BACKGROUND_COLOR, 0xFFFF7800);
weekText_[i].SetStyle(OHOS::STYLE_BORDER_RADIUS, GetHeight() >> 1);
}
Add(&weekText_[i]);
}
}
void TjdUiAppMainPageTool::CalendarView::CalculateWeekDays(const struct rtc_time &curDate, int weekDay[7])
{
int currentDay = curDate.tm_mday;
int currentWeekDay = curDate.tm_wday;
for (int i = 0; i < 7; ++i) {
weekDay[i] = currentDay - currentWeekDay + i;
}
int daysInMonth = GetDaysInMonth(curDate.tm_year, curDate.tm_mon);
for (int i = 0; i < 7; ++i) {
if (weekDay[i] < 1) {
int prevMonth = curDate.tm_mon - 1;
int prevYear = curDate.tm_year;
if (prevMonth < 1) {
prevMonth = 12;
prevYear -= 1;
}
int prevMonthDays = GetDaysInMonth(prevYear, prevMonth);
weekDay[i] = prevMonthDays + weekDay[i];
} else if (weekDay[i] > daysInMonth) {
int nextMonth = curDate.tm_mon + 1;
int nextYear = curDate.tm_year;
if (nextMonth > 12) {
nextMonth = 1;
nextYear += 1;
}
weekDay[i] = weekDay[i] - daysInMonth;
}
}
}
int TjdUiAppMainPageTool::CalendarView::GetDaysInMonth(int year, int month)
{
static const int daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (month == 2 && IsLeapYear(year)) {
return 29;
}
return daysInMonth[month - 1];
}
#pragma endregion
class TjdUiAppMainPageTool::ToolOnClickListener : public OHOS::UIView::OnClickListener
{
public:
virtual bool OnClick(OHOS::UIView &view, const OHOS::ClickEvent &event)
{
std::string viewId = view.GetViewId();
if (viewId == CALCULATOR_VIEW_ID) {
OHOS::NativeAbility::GetInstance().ChangeSlice(TjdUiAppViewId::TJD_APP_VIEW_CALCULATOR);
return true;
} else if (viewId == STOPWATCH_VIEW_ID) {
OHOS::NativeAbility::GetInstance().ChangeSlice(TjdUiAppViewId::TJD_APP_VIEW_STOPWATCH);
return true;
} else if (viewId == TIMER_VIEW_ID) {
OHOS::NativeAbility::GetInstance().ChangeSlice(TjdUiAppViewId::TJD_APP_VIEW_TIMER);
return true;
} else if (viewId == ALARM_CLOCK_VIEW_ID) {
OHOS::NativeAbility::GetInstance().ChangeSlice(TjdUiAppViewId::TJD_APP_VIEW_ALARM);
return true;
}
return false;
}
};
static TjdUiAppMainPageTool *g_calendarPage = nullptr;
TjdUiAppMainPageTool::TjdUiAppMainPageTool()
{
SetPosition(0, 0, OHOS::Screen::GetInstance().GetWidth(), OHOS::Screen::GetInstance().GetHeight());
g_calendarPage = this;
}
TjdUiAppMainPageTool::~TjdUiAppMainPageTool()
{
UnLoad();
g_calendarPage = nullptr;
}
TjdUiAppMainPageTool *TjdUiAppMainPageTool::GetInstance(void) { return g_calendarPage; }
void TjdUiAppMainPageTool::PreLoad(void)
{
static_print_debug("TjdUiAppMainPageTool::PreLoad");
// OHOS::MemCheck::GetInstance()->EnableLeakCheck(true);
if (!viewiInitStatus) {
OHOS::ImageCacheManager::GetInstance().LoadAllInMultiRes(MAIN_TOOL_IMAGE_BIN_PATH);
InitView();
UpdateValue();
viewiInitStatus = true;
}
}
void TjdUiAppMainPageTool::UnLoad(void)
{
static_print_debug("TjdUiAppMainPageTool::UnLoad");
if (viewiInitStatus) {
OHOS::ImageCacheManager::GetInstance().UnloadAllInMultiRes(MAIN_TOOL_IMAGE_BIN_PATH);
RemoveAll();
if (container_) {
container_->RemoveAll();
delete container_;
container_ = nullptr;
}
if (date_) {
delete date_;
date_ = nullptr;
}
if (calendarView_) {
delete calendarView_;
calendarView_ = nullptr;
}
if (calculator_) {
delete calculator_;
calculator_ = nullptr;
}
if (stopWatch_) {
delete stopWatch_;
stopWatch_ = nullptr;
}
if (timer_) {
delete timer_;
timer_ = nullptr;
}
if (alarmClockBg_) {
delete alarmClockBg_;
alarmClockBg_ = nullptr;
}
if (alarmClock_) {
delete alarmClock_;
alarmClock_ = nullptr;
}
if (alarmClockLabel_) {
delete alarmClockLabel_;
alarmClockLabel_ = nullptr;
}
if (toolOnClickListener_) {
delete toolOnClickListener_;
toolOnClickListener_ = nullptr;
}
if (circleProgress_) {
delete circleProgress_;
circleProgress_ = nullptr;
}
if (circleProgressBg_) {
delete circleProgressBg_;
circleProgressBg_ = nullptr;
}
viewiInitStatus = false;
}
// OHOS::MemCheck::GetInstance()->EnableLeakCheck(false);
}
void TjdUiAppMainPageTool::InitView(void)
{
auto &image = OHOS::ImageCacheManager::GetInstance();
container_ = new OHOS::UIViewGroup();
container_->SetPosition(0, 0, OHOS::Screen::GetInstance().GetWidth(), OHOS::Screen::GetInstance().GetHeight());
toolOnClickListener_ = new ToolOnClickListener();
date_ = new OHOS::UILabel();
date_->SetFont(TJD_DIN_MEDIUM_FONT_FILENAME, 36);
date_->SetText("2024.10");
date_->SetLineBreakMode(OHOS::UILabel::LINE_BREAK_WRAP);
date_->SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
date_->SetPosition(171, 31, 124, 27);
container_->Add(date_);
struct rtc_time localTime = {};
tjd_driver_rtc_get_ops()->get_rtc_time(&localTime);
calendarView_ = new CalendarView(localTime);
container_->Add(calendarView_);
calculator_ = new OHOS::UIImageView();
calculator_->SetViewId(CALCULATOR_VIEW_ID);
calculator_->SetTouchable(true);
calculator_->SetOnClickListener(toolOnClickListener_);
calculator_->SetPosition(74, 128, 192, 210);
auto imageInfo = image.LoadOneInMultiRes(IMG_MAIN_TOOL_CALCULATOR, MAIN_TOOL_IMAGE_BIN_PATH);
calculator_->SetSrc(imageInfo);
container_->Add(calculator_);
stopWatch_ = new OHOS::UIImageView();
stopWatch_->SetViewId(STOPWATCH_VIEW_ID);
stopWatch_->SetTouchable(true);
stopWatch_->SetOnClickListener(toolOnClickListener_);
stopWatch_->SetPosition(290, 128, 101, 100);
imageInfo = image.LoadOneInMultiRes(IMG_MAIN_TOOL_STOPWATCH, MAIN_TOOL_IMAGE_BIN_PATH);
stopWatch_->SetSrc(imageInfo);
container_->Add(stopWatch_);
timer_ = new OHOS::UIImageView();
timer_->SetViewId(TIMER_VIEW_ID);
timer_->SetTouchable(true);
timer_->SetOnClickListener(toolOnClickListener_);
timer_->SetPosition(291, 235, 101, 101);
imageInfo = image.LoadOneInMultiRes(IMG_MAIN_TOOL_TIMER, MAIN_TOOL_IMAGE_BIN_PATH);
timer_->SetSrc(imageInfo);
container_->Add(timer_);
alarmClockBg_ = new OHOS::UIView();
alarmClockBg_->SetViewId(ALARM_CLOCK_VIEW_ID);
alarmClockBg_->SetTouchable(true);
alarmClockBg_->SetOnClickListener(toolOnClickListener_);
alarmClockBg_->SetPosition(122, 354, 220, 72);
alarmClockBg_->SetStyle(OHOS::STYLE_BORDER_RADIUS, alarmClockBg_->GetWidth() >> 1);
alarmClockBg_->SetStyle(OHOS::STYLE_BACKGROUND_OPA, OHOS::OPA_OPAQUE);
alarmClockBg_->SetStyle(OHOS::STYLE_BACKGROUND_COLOR, 0xFF262626);
alarmClockBg_->SetViewId("alarmClockBg");
container_->Add(alarmClockBg_);
alarmClock_ = new OHOS::UIImageView();
alarmClock_->SetTouchable(true);
alarmClock_->SetViewId(ALARM_CLOCK_VIEW_ID);
alarmClock_->SetOnClickListener(toolOnClickListener_);
alarmClock_->SetPosition(145, 366, 50, 50);
imageInfo = image.LoadOneInMultiRes(IMG_MAIN_TOOL_ALARM_CLOCK, MAIN_TOOL_IMAGE_BIN_PATH);
alarmClock_->SetSrc(imageInfo);
container_->Add(alarmClock_);
alarmClockLabel_ = new OHOS::UILabel();
alarmClockLabel_->SetTouchable(true);
alarmClockLabel_->SetViewId(ALARM_CLOCK_VIEW_ID);
alarmClockLabel_->SetOnClickListener(toolOnClickListener_);
alarmClockLabel_->SetFont(TJD_DIN_MEDIUM_FONT_FILENAME, 36);
alarmClockLabel_->SetText("06:00");
alarmClockLabel_->SetLineBreakMode(OHOS::UILabel::LINE_BREAK_WRAP);
alarmClockLabel_->SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
alarmClockLabel_->SetPosition(219, 368, 88, 27);
container_->Add(alarmClockLabel_);
circleProgressBg_ = new OHOS::UIImageView();
circleProgressBg_->SetPosition(7, 7, 452, 452);
circleProgressBg_->SetSrc(image.LoadOneInMultiRes(IMG_MAIN_TOOL_TOOL_PROGRESS, MAIN_TOOL_IMAGE_BIN_PATH));
container_->Add(circleProgressBg_);
// circleProgress_ = new OHOS::UICircleProgress();
// auto screenWidth = OHOS::Screen::GetInstance().GetWidth();
// auto screenHeight = OHOS::Screen::GetInstance().GetHeight();
// circleProgress_->SetPosition(0, 0, screenWidth, screenHeight);
// circleProgress_->SetCenterPosition(screenWidth / 2, screenHeight / 2);
// circleProgress_->SetRadius(233);
// circleProgress_->SetBackgroundStyle(OHOS::STYLE_LINE_WIDTH, 30);
// circleProgress_->SetForegroundStyle(OHOS::STYLE_LINE_WIDTH, 30);
// circleProgress_->SetStartAngle(0);
// circleProgress_->SetEndAngle(360);
// circleProgress_->SetImage(image.LoadOneInMultiRes(IMG_MAIN_TOOL_TOOL_PROGRESS, MAIN_TOOL_IMAGE_BIN_PATH),
// image.LoadOneInMultiRes(IMG_MAIN_TOOL_TOOL_BJ, MAIN_TOOL_IMAGE_BIN_PATH));
// circleProgress_->SetLineColor(OHOS::Color::Red());
// circleProgress_->SetProgressImagePosition(7, 7);
// circleProgress_->SetBackgroundImagePosition(7, 7);
// container_->Add(circleProgress_);
Add(container_);
}
static bool IsLeapYear(int year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); }
void TjdUiAppMainPageTool::UpdateValue(void)
{
std::stringstream ss;
struct rtc_time localTime = {};
tjd_driver_rtc_get_ops()->get_rtc_time(&localTime);
uint8_t size = sql_alarm_get_alarm_number(nullptr);
uint8_t alarm_num[size];
uint8_t *array_ptr = alarm_num;
sql_alarm_get_alarm_index_list(&array_ptr);
int nearestHour = 0;
int nearestMinute = 0;
int min_time_diff = 24 * 60; // 最大时间差为一天的分钟数
bool found = false;
// 找出最近的闹钟
for (int i = 0; i < size; i++) {
uint8_t hour;
uint8_t minute;
sql_alarm_get_time(alarm_num[i], &hour, &minute);
int alarm_time_in_minutes = hour * 60 + minute;
int current_time_in_minutes = localTime.tm_hour * 60 + localTime.tm_min;
int time_diff = alarm_time_in_minutes - current_time_in_minutes;
if (time_diff < 0) {
time_diff += 24 * 60; // 如果时间差为负数,说明闹钟时间在第二天
}
if (time_diff < min_time_diff) {
min_time_diff = time_diff;
nearestHour = hour;
nearestMinute = minute;
found = true;
}
}
if (found && alarmClockLabel_) {
ss.str("");
ss << std::setw(2) << std::setfill('0') << nearestHour << ":" << std::setw(2) << std::setfill('0')
<< nearestMinute;
alarmClockLabel_->SetText(ss.str().c_str());
}
if (date_) {
ss.str("");
ss << localTime.tm_year << "." << std::setw(2) << std::setfill('0') << localTime.tm_mon;
date_->SetText(ss.str().c_str());
}
if (circleProgress_) {
const int daysInYear = IsLeapYear(localTime.tm_year) ? 366 : 365;
const int progress = (localTime.tm_yday * 100) / daysInYear;
circleProgress_->SetValue(progress);
}
}
} // namespace TJD