#include "TjdUiAppCalendarView.h" #include "TjdUiImageIds.h" #include "TjdUiMemManage.h" #include "TjdUiMultiLanguageExt.h" #include "animator/animator_manager.h" #include "color.h" #include "common/image_cache_manager.h" #include "gfx_utils/color.h" #include "gfx_utils/mem_check.h" #include "graphic_service.h" #include "rtc_api.h" #include "sys_config.h" #include "ui_view.h" using namespace OHOS; namespace TJD { #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 static TjdUiAppCalendarView *g_pv_CalendarView = nullptr; static CalendarView *g_pv_CurrentDateView = nullptr; #define CALENDAR_IMAGE_BIN_PATH TJD_IMAGE_PATH "img_calendar.bin" // clang-format off static inline int16_t HorizontalCenter(int16_t width, int16_t parentWidth) { return (parentWidth - width) / 2; } static inline int16_t VerticalCenter(int16_t height, int16_t parentHeight) { return (parentHeight - height) / 2; } static inline void InitLabelHorCenter(OHOS::UILabel &label, uint8_t size, int16_t y, int16_t target, const char *text) { label.SetFont(TJD_VECTOR_FONT_FILENAME, size); label.SetText(text); label.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); label.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); label.SetPosition(HorizontalCenter(label.GetWidth(), target), y); } static inline void InitLabelVerCenter(OHOS::UILabel &label, uint8_t size, int16_t x, int16_t target, const char *text) { label.SetFont(TJD_VECTOR_FONT_FILENAME, size); label.SetText(text); label.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); label.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); label.SetPosition(x, VerticalCenter(label.GetHeight(), target)); } // clang-format on TjdUiAppCalendarView::TjdUiAppCalendarView() { MemCheck::GetInstance()->EnableLeakCheck(true); g_pv_CalendarView = this; } TjdUiAppCalendarView::~TjdUiAppCalendarView() { printf("TjdUiAppCalendarView::~TjdUiAppCalendarView\n"); g_pv_CalendarView = nullptr; MemCheck::GetInstance()->EnableLeakCheck(false); } TjdUiAppCalendarView *TjdUiAppCalendarView::GetInstance(void) { return g_pv_CalendarView; } void TjdUiAppCalendarView::OnStart() { static_print_info("TjdUiAppCalendarView::OnStart"); View::OnStart(); OHOS::ImageCacheManager::GetInstance().LoadAllInMultiRes(CALENDAR_IMAGE_BIN_PATH); if (mainView_ == nullptr) { mainView_ = new OHOS::UIScrollView(); } if (calendarView_ == nullptr) { calendarView_ = new CalendarView(); } mainView_->Add(calendarView_); mainView_->SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); if (OHOS::PageTransitionMgr::GetInstance().GetTopSlideBackImage() == nullptr) { mainView_->SetOnDragListener(&TjdUiAppCalendarPresenter::GetInstance()); } AddViewToRootContainer(mainView_); } void TjdUiAppCalendarView::OnStop() { if (mainView_ != nullptr) { OHOS::RootView::GetInstance()->Remove(mainView_); mainView_->RemoveAll(); delete mainView_; mainView_ = nullptr; } if (calendarView_ != nullptr) { calendarView_->RemoveAll(); delete calendarView_; calendarView_ = nullptr; } OHOS::ImageCacheManager::GetInstance().UnloadAllInMultiRes(CALENDAR_IMAGE_BIN_PATH); } uint8_t TjdUiAppCalendarView::GetDaysOfCurrentMonth(uint8_t month, uint16_t year) { uint8_t daysInMonth = 0; switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: daysInMonth = 31; break; case 4: case 6: case 9: case 11: daysInMonth = 30; break; case 2: // 判断是否为闰年 if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) daysInMonth = 29; else daysInMonth = 28; break; default: daysInMonth = -1; // 处理无效月份 break; } return daysInMonth; } int TjdUiAppCalendarView::GetDaysOfCurrentWeek(int year, int month, int day) { struct tm time_in = {0}; time_in.tm_year = year - 1900; // 年份需要减去1900 time_in.tm_mon = month - 1; // 月份从0开始,所以需要减去1 time_in.tm_mday = day; // 设置为每月的第一天 time_t time_sec = mktime(&time_in); // 将时间转换为日历时间 if (time_sec == -1) { static_print_debug("Error: unable to make time using mktime"); } struct tm *time_out = localtime(&time_sec); return time_out->tm_wday; // 返回星期几(0-6,分别代表周日到周六) } CalendarView::CalendarView() { g_pv_CurrentDateView = this; Resize(OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); SetTouchable(true); // InitLabelHorCenter(lbTitle_, 34, 17, 466, "日历"); lbTitle_.SetFont(TJD_VECTOR_FONT_FILENAME, 34); lbTitle_.SetTextId(STR_ID_16); lbTitle_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); lbTitle_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); lbTitle_.SetPosition(HorizontalCenter(lbTitle_.GetWidth(), 466), 17); uint8_t column = 0; char tempstr[10] = {0}; rtc_class_ops *rtc = tjd_driver_rtc_get_ops(); struct rtc_time localTime; rtc->get_rtc_time(&localTime); curDateInfo.year = localTime.tm_year; curDateInfo.month = localTime.tm_mon; curDateInfo.day = localTime.tm_mday; daysInMonth = TjdUiAppCalendarView::GetInstance()->GetDaysOfCurrentMonth(curDateInfo.month, curDateInfo.year); weekDaysOfMonth = TjdUiAppCalendarView::GetInstance()->GetDaysOfCurrentWeek( curDateInfo.year, curDateInfo.month, 1); // 每月第一天是星期几(0-6,分别代表周日到周六) for (uint8_t i = 0; i < MAX_DAYS_OF_MONTH; i++) { if (weekDaysOfMonth > 6) { weekDaysOfMonth = 0; column++; } CalendarLabel[i].SetPosition(63 + (30 * weekDaysOfMonth) + (23 * weekDaysOfMonth), 126 + 32 * column + 16 * column); CalendarLabel[i].Resize(40, 40); CalendarLabel[i].SetStyle(STYLE_TEXT_FONT, TJD_FONT_SIZE_24); memset(tempstr, 0, strlen(tempstr)); sprintf(tempstr, "%d", i + 1); CalendarLabel[i].SetText(tempstr); if (weekDaysOfMonth < 1 || weekDaysOfMonth > 5) { CalendarLabel[i].SetTextColor(Color::GetColorFromRGBA(0xff, 0xff, 0xff, 0x50)); CalendarLabel[i].SetStyle(STYLE_BACKGROUND_OPA, 0xff); } if (i + 1 == curDateInfo.day) { CalendarLabel[i].SetStyle(STYLE_BACKGROUND_COLOR, 0xFFFF7800); CalendarLabel[i].SetStyle(STYLE_BACKGROUND_OPA, 0xff); CalendarLabel[i].SetStyle(STYLE_BORDER_RADIUS, 20); } CalendarLabel[i].SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); CalendarLabel[i].SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); CalendarLabel[i].SetFont(TJD_VECTOR_FONT_FILENAME, TJD_FONT_SIZE_28); if (i >= daysInMonth) { CalendarLabel[i].SetVisible(false); } Add(&CalendarLabel[i]); weekDaysOfMonth++; } int resId = IMG_CALENDAR_WEEK_CH; TjdUiLanguageId language = TjdUiMultiLanguageExt::GetCurrentLanguage(); if (language == LANGUAGE_ID_CHS) { resId = IMG_CALENDAR_WEEK_CH; } else { resId = IMG_CALENDAR_WEEK_EN; } ImageInfo *imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(resId, CALENDAR_IMAGE_BIN_PATH); if (imgInfo == nullptr) { static_print_debug("imgWeek_ load image error"); } imgWeek_.SetSrc(imgInfo); imgWeek_.SetPosition(61, 72); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_CALENDAR_BJ_LINE, CALENDAR_IMAGE_BIN_PATH); if (imgInfo == nullptr) { static_print_debug("bjLine_ load image error"); } bjLine_.SetSrc(imgInfo); bjLine_.SetPosition(39, 104); uint8_t Weekday = TjdUiAppCalendarView::GetInstance()->GetDaysOfCurrentWeek( curDateInfo.year, curDateInfo.month, curDateInfo.day); // 每月第一天是星期几(0-6,分别代表周日到周六) curWeekday_.SetPosition(49 + Weekday * 50 + 3 * Weekday, 103); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_CALENDAR_WEEK_SELECTED, CALENDAR_IMAGE_BIN_PATH); if (imgInfo == nullptr) { static_print_debug("curWeekday_ load image error"); } curWeekday_.SetSrc(imgInfo); dateLabel_.SetPosition(194, 397, 80, 17); dateLabel_.SetStyle(STYLE_TEXT_FONT, TJD_FONT_SIZE_24); memset(tempstr, 0, strlen(tempstr)); sprintf(tempstr, "%d.%02d", curDateInfo.year, curDateInfo.month); dateLabel_.SetText(tempstr); dateLabel_.SetTextColor(Color::GetColorFromRGB(255, 120, 0)); dateLabel_.SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); dateLabel_.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); dateLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, TJD_FONT_SIZE_24); iconLeft_.SetPosition(121, 407, 12, 18); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_CALENDAR_ICON_LEFT, CALENDAR_IMAGE_BIN_PATH); if (imgInfo == nullptr) { static_print_debug("iconLeft_ load image error"); } iconLeft_.SetSrc(imgInfo); iconRight_.SetPosition(333, 407, 12, 18); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_CALENDAR_ICON_RIGHT, CALENDAR_IMAGE_BIN_PATH); if (imgInfo == nullptr) { static_print_debug("iconRight_ load image error"); } iconRight_.SetSrc(imgInfo); touchOnClickedView_.SetPosition(0, 400, 466, 66); touchOnClickedView_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff000000); touchOnClickedView_.SetTouchable(true); touchOnClickedView_.SetStyle(STYLE_BACKGROUND_OPA, 0); touchOnClickedView_.SetOnClickListener(&TjdUiAppCalendarPresenter::GetInstance()); Add(&lbTitle_); Add(&dateLabel_); Add(&imgWeek_); Add(&bjLine_); Add(&curWeekday_); Add(&touchOnClickedView_); Add(&iconLeft_); Add(&iconRight_); } bool CalendarView::OnDragStartEvent(const OHOS::DragEvent &event) { if ((event.GetDragDirection() == OHOS::DragEvent::DIRECTION_LEFT_TO_RIGHT) && event.GetStartPoint().x > 30) { leftStartX_ = event.GetStartPoint().x; } else if ((event.GetDragDirection() == OHOS::DragEvent::DIRECTION_RIGHT_TO_LEFT) && event.GetStartPoint().x > 30) { rightStartX_ = event.GetStartPoint().x; } if (event.GetStartPoint().x >= 120) { isExit_ = false; return true; } isExit_ = true; return OHOS::UIScrollView::OnDragStartEvent(event); } bool CalendarView::OnDragEvent(const OHOS::DragEvent &event) { if (isExit_ == false) { return true; } if ((event.GetDragDirection() == OHOS::DragEvent::DIRECTION_LEFT_TO_RIGHT) && (event.GetDeltaX() > 20) && (event.GetDeltaX() > (2 * MATH_ABS(event.GetDeltaY())))) { isExit_ = true; return OHOS::UIScrollView::OnDragEvent(event); } if (isExit_) { return OHOS::UIScrollView::OnDragEvent(event); } return true; } bool CalendarView::OnDragEndEvent(const OHOS::DragEvent &event) { if (isExit_ == false) { uint16_t year = 0; uint8_t month = 0; std::string dateString = (char *)(CalendarView::GetInstance()->GetDateLabel()->GetText()); // 查找点号的位置 size_t dotPos = dateString.find('.'); if (dotPos != std::string::npos) { // 提取年份和月份 std::string yearStr = dateString.substr(0, dotPos); std::string monthStr = dateString.substr(dotPos + 1); year = std::stoi(yearStr); month = std::stoi(monthStr); } CalendarView::CurrentDateInfo curDateInfo = GetCurrentDateInfo(); if ((event.GetDragDirection() == OHOS::DragEvent::DIRECTION_LEFT_TO_RIGHT) && event.GetStartPoint().x > 30) { leftEndX_ = event.GetLastPoint().x; if (leftEndX_ - leftStartX_ > 40) { month--; if (month == 0) { month = 12; year--; } UpdateInfo(curDateInfo, month, year); } } else if ((event.GetDragDirection() == OHOS::DragEvent::DIRECTION_RIGHT_TO_LEFT) && event.GetStartPoint().x > 30) { rightEndX_ = event.GetLastPoint().x; if (rightStartX_ - rightEndX_ > 40) { month++; if (month == 13) { month = 1; year++; } UpdateInfo(curDateInfo, month, year); } } isExit_ = true; return true; } isExit_ = true; return OHOS::UIScrollView::OnDragEndEvent(event); } CalendarView::~CalendarView() { printf("CalendarView::~CalendarView()\n"); g_pv_CurrentDateView = nullptr; RemoveAll(); } CalendarView *CalendarView::GetInstance() { return g_pv_CurrentDateView; } void CalendarView::UpdateInfo(CurrentDateInfo curDateInfo, uint8_t month, uint16_t year) { static_print_debug("CalendarView::UpdateInfo"); g_pv_CurrentDateView = this; uint8_t column = 0; daysInMonth = TjdUiAppCalendarView::GetInstance()->GetDaysOfCurrentMonth(month, year); weekDaysOfMonth = TjdUiAppCalendarView::GetInstance()->GetDaysOfCurrentWeek(year, month, 1); if (curDateInfo.month == month && curDateInfo.year == year) { curWeekday_.SetVisible(true); } else { curWeekday_.SetVisible(false); } for (uint8_t i = 0; i < MAX_DAYS_OF_MONTH; i++) { if (weekDaysOfMonth > 6) { weekDaysOfMonth = 0; column++; } CalendarLabel[i].SetTextColor(Color::White()); CalendarLabel[i].SetStyle(STYLE_BACKGROUND_COLOR, 0xFF000000); CalendarLabel[i].SetPosition(63 + (30 * weekDaysOfMonth) + (23 * weekDaysOfMonth), 126 + 32 * column + 16 * column); if (weekDaysOfMonth < 1 || weekDaysOfMonth > 5) { CalendarLabel[i].SetTextColor(Color::GetColorFromRGBA(0xff, 0xff, 0xff, 0x50)); CalendarLabel[i].SetStyle(STYLE_BACKGROUND_OPA, 0xff); } if (i + 1 == curDateInfo.day && curDateInfo.month == month && curDateInfo.year == year) { CalendarLabel[i].SetStyle(STYLE_BACKGROUND_COLOR, 0xFFFF7800); CalendarLabel[i].SetStyle(STYLE_BACKGROUND_OPA, 0xff); CalendarLabel[i].SetStyle(STYLE_BORDER_RADIUS, 20); } if (i + 1 <= daysInMonth) CalendarLabel[i].SetVisible(true); else CalendarLabel[i].SetVisible(false); weekDaysOfMonth++; } char tempstr[10] = {0}; sprintf(tempstr, "%d.%02d", year, month); dateLabel_.SetText(tempstr); dateLabel_.Invalidate(); } } // namespace TJD