/*---------------------------------------------------------------------------- * 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 #include #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