/*---------------------------------------------------------------------------- * Copyright (c) TJD Technologies Co., Ltd. 2024. All rights reserved. * * Description: TjdUiAppCompassView.cpp * * Author: wuchangxin@ss-tjd.com * * Create: 2025-02-25 *--------------------------------------------------------------------------*/ #include "TjdUiAppCompassView.h" #include "TjdUiAppCompassModel.h" #include "TjdUiImageIds.h" #include "TjdUiMemManage.h" #include "TjdUiMultiLanguageExt.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 "hal_tick.h" #include "style.h" #include "sys_config.h" #include "ui_label_ext.h" #include "ui_view.h" #include #include #include using namespace OHOS; namespace TJD { #define ENABLE_PRINT_INFO 0 #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 #define COMPASS_IMAGE_BIN_PATH TJD_IMAGE_PATH "img_compass.bin" #define DATA_ANIMATOR_CENTER \ { \ 37.0F, 46.0F \ } #define COMPASS_SHOW_BG_ID "compassBg" #define COMPASS_SHOW_DIRECTION_ID "compassDirection_" #define COMPASS_SHOW_AZIMUTH_ID "compassAzimuth" #define SHOW_ANIMATOR_CENTER \ { \ 233.0F, 233.0F \ } static float lastAngle_{0}; static float radio{0}; static char azimuthStr[10] = {0}; static char dataStr[10] = {0}; static float roll{0}; static OHOS::Animator *animator_{nullptr}; static OHOS::Animator *dataAnimator_{nullptr}; static uint8_t calibrationTicks_{0}; static uint8_t calibrationSuccessCount_{0}; static osTimerId_t g_CalibrationTimerId{nullptr}; static TjdUiAppCompassView *g_pv_CompassMainView = nullptr; CompassView TjdUiAppCompassView::currentViewIndex_ = VIEW_COMPASS_MAX; // 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 bool CompassUIScrollView::OnDragStartEvent(const OHOS::DragEvent &event) { if (TjdUiAppCompassView::currentViewIndex_ != CompassView::VIEW_COMPASS_CALIBRATION && TjdUiAppCompassView::currentViewIndex_ != CompassView::VIEW_COMPASS_SHOW) { return true; } isOnStart_ = true; return OHOS::UIScrollViewNested::OnDragStartEvent(event); } bool CompassUIScrollView::OnDragEvent(const OHOS::DragEvent &event) { if (!isOnStart_) { return true; } if (TjdUiAppCompassView::currentViewIndex_ != CompassView::VIEW_COMPASS_CALIBRATION && TjdUiAppCompassView::currentViewIndex_ != CompassView::VIEW_COMPASS_SHOW) { return true; } return OHOS::UIScrollViewNested::OnDragEvent(event); } bool CompassUIScrollView::OnDragEndEvent(const OHOS::DragEvent &event) { if (!isOnStart_) { return true; } isOnStart_ = false; if (TjdUiAppCompassView::currentViewIndex_ != CompassView::VIEW_COMPASS_CALIBRATION && TjdUiAppCompassView::currentViewIndex_ != CompassView::VIEW_COMPASS_SHOW) { return true; } return OHOS::UIScrollViewNested::OnDragEndEvent(event); } TjdUiAppCompassView::TjdUiAppCompassView() { // OHOS::MemCheck::GetInstance()->EnableLeakCheck(true); g_pv_CompassMainView = this; } TjdUiAppCompassView::~TjdUiAppCompassView() { printf("TjdUiAppCompassView::~TjdUiAppCompassView\n"); g_pv_CompassMainView = nullptr; // OHOS::MemCheck::GetInstance()->EnableLeakCheck(false); } TjdUiAppCompassView *TjdUiAppCompassView::GetInstance(void) { return g_pv_CompassMainView; } void TjdUiAppCompassView::OnStart() { static_print_info("TjdUiAppCompassView::OnStart"); if (mainContainer_ == nullptr) { mainContainer_ = new CompassUIScrollView(); } mainContainer_->SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); // mainContainer_->SetOnDragListener(&TjdUiAppCompassPresenter::GetInstance()); auto compassModel = TjdUiAppCompassModel::GetInstance(); compassModel->MSensorOpen(); if (compassModel->GetAccuracy() < 3) { ShowView(VIEW_COMPASS_CALIBRATION); } else { ShowView(VIEW_COMPASS_SHOW); } AddViewToRootContainer(mainContainer_); } void TjdUiAppCompassView::ShowView(CompassView showIndex) { if (showIndex < 0 || showIndex >= VIEW_COMPASS_MAX) { return; } InitTargetView(showIndex); if (currentViewIndex_ >= 0 && currentViewIndex_ < VIEW_COMPASS_MAX && viewManager_[currentViewIndex_] != nullptr) { viewManager_[currentViewIndex_]->HideView(); } if (viewManager_[showIndex] != nullptr) { viewManager_[showIndex]->ShowView(); } currentViewIndex_ = showIndex; } void TjdUiAppCompassView::InitTargetView(CompassView index) { if (viewManager_[index] != nullptr) { return; } // clang-format off switch (index) { case VIEW_COMPASS_CALIBRATION: viewManager_[index] = new CompassCalibrationView(); break; case VIEW_COMPASS_SHOW: viewManager_[index] = new CompassShowView(); break; case VIEW_COMPASS_DATA: viewManager_[index] = new CompassDataView(); break; default: break; } // clang-format on if (viewManager_[index] == nullptr) { return; } viewManager_[index]->SetPosition(0, 0); viewManager_[index]->SetVisible(false); mainContainer_->Add(viewManager_[index]); } void TjdUiAppCompassView::OnStop() { calibrationSuccessCount_ = 0; TjdUiAppCompassModel::GetInstance()->MSensorClose(); TjdUiAppCompassModel::GetInstance()->OpenAutoScreenOff(); if (mainContainer_ != nullptr) { mainContainer_->RemoveAll(); delete mainContainer_; mainContainer_ = nullptr; } for (uint8_t i = 0; i < VIEW_COMPASS_MAX; i++) { if (viewManager_[i] != nullptr) { delete viewManager_[i]; viewManager_[i] = nullptr; } } OHOS::ImageCacheManager::GetInstance().UnloadAllInMultiRes(COMPASS_IMAGE_BIN_PATH); } #pragma region 指南针校准页面 static void CalibrationTimerFunc(void *arg) { // printf("CalibrationTimerFunc, ticks:%d,accuracy:%d\n", calibrationTicks_, // TjdUiAppCompassModel::GetInstance()->GetAccuracy()); if (calibrationTicks_ < 30) { calibrationTicks_ += 1; if (TjdUiAppCompassModel::GetInstance()->GetAccuracy() < 3) { //临时调试 calibrationSuccessCount_ = 0; return; } else { calibrationSuccessCount_++; // printf("calibrationSuccessCount_:%d\n", calibrationSuccessCount_); if (calibrationSuccessCount_ >= 5) { //校准成功次数大于等于10,进入显示页面 osTimerStop(g_CalibrationTimerId); GraphicService::GetInstance()->PostGraphicEvent([]() { auto CompassView = TjdUiAppCompassView::GetInstance(); CompassView->ShowView(VIEW_COMPASS_SHOW); }); } } } else { TjdUiAppCompassModel::GetInstance()->OpenAutoScreenOff(); osTimerStop(g_CalibrationTimerId); GraphicService::GetInstance()->PostGraphicEvent([]() { OHOS::NativeAbility::GetInstance().ChangePreSlice(); }); } } CompassCalibrationView::CompassCalibrationView() { SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); SetStyle(STYLE_BACKGROUND_OPA, 0xff); if (OHOS::PageTransitionMgr::GetInstance().GetTopSlideBackImage() == nullptr) { SetOnDragListener(&TjdUiAppCompassPresenter::GetInstance()); } ImgGuide_.SetPosition(87, 119); auto resInfo = OHOS::ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_COMPASS_ICON_PROOFREAD, COMPASS_IMAGE_BIN_PATH); if (resInfo) { ImgGuide_.SetSrc(resInfo); } g_CalibrationTimerId = osTimerNew((osTimerFunc_t)CalibrationTimerFunc, osTimerPeriodic, NULL, NULL); // InitLabelHorCenter(tip_, 36, 287, 466, "请按图指示\n旋转手表进行校对"); tip_.SetFont(TJD_VECTOR_FONT_FILENAME, 36); tip_.SetTextId(STR_ID_315); tip_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_WRAP); tip_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); tip_.SetPosition(87, 287, 292, 82); Add(&ImgGuide_); Add(&tip_); } CompassCalibrationView::~CompassCalibrationView() { if (g_CalibrationTimerId != nullptr) { osTimerDelete(g_CalibrationTimerId); g_CalibrationTimerId = nullptr; } RemoveAll(); } void CompassCalibrationView::ShowView() { calibrationTicks_ = 0; SetVisible(true); osTimerStart(g_CalibrationTimerId, 1000); TjdUiAppCompassModel::GetInstance()->CloseAutoScreenOff(30000); } void CompassCalibrationView::HideView() { SetVisible(false); } #pragma endregion #pragma region 指南针显示页面 void ShowViewAnimatorCallback::Callback(OHOS::UIView *view) { TjdUiAppCompassModel::GetInstance()->CloseAutoScreenOff(100); // printf("GetAccuracy() = %d\n", TjdUiAppCompassModel::GetInstance()->GetAccuracy()); if (TjdUiAppCompassModel::GetInstance()->GetAccuracy() < 3) { auto CompassView = TjdUiAppCompassView::GetInstance(); CompassView->ShowView(VIEW_COMPASS_CALIBRATION); animator_->Stop(); return; } radio = TjdUiAppCompassModel::GetInstance()->GetAzimuth(); compassBg_->Rotate(-radio, SHOW_ANIMATOR_CENTER); if (radio > 22.5F && radio <= 67.5F) { direction_->SetText("NE"); } else if (radio > 67.5F && radio <= 112.5F) { direction_->SetText("E"); } else if (radio > 112.5F && radio <= 157.5F) { direction_->SetText("SE"); } else if (radio > 157.5F && radio <= 202.5F) { direction_->SetText("S"); } else if (radio > 202.5F && radio <= 247.5F) { direction_->SetText("SW"); } else if (radio > 247.5F && radio <= 292.5F) { direction_->SetText("W"); } else if (radio > 292.5F && radio <= 337.5F) { direction_->SetText("NW"); } else { direction_->SetText("N"); } memset(azimuthStr, 0, sizeof(azimuthStr)); sprintf(azimuthStr, "~%.1f°", radio); azimuth_->SetText(azimuthStr); // printf("radio:%f\n", radio); } CompassShowView::CompassShowView() { SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); SetStyle(STYLE_BACKGROUND_OPA, 0xff); if (OHOS::PageTransitionMgr::GetInstance().GetTopSlideBackImage() == nullptr) { SetOnDragListener(&TjdUiAppCompassPresenter::GetInstance()); } compassBg_.SetPosition(0, 0); auto resInfo = OHOS::ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_COMPASS_FACE, COMPASS_IMAGE_BIN_PATH); if (resInfo) { compassBg_.SetSrc(resInfo); } compassBg_.SetViewId(COMPASS_SHOW_BG_ID); compassPoint_.SetPosition(223, 36); resInfo = OHOS::ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_COMPASS_POINTER, COMPASS_IMAGE_BIN_PATH); if (resInfo) { compassPoint_.SetSrc(resInfo); } compassFg_.SetPosition(125, 125); resInfo = OHOS::ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_COMPASS_ROUND, COMPASS_IMAGE_BIN_PATH); if (resInfo) { compassFg_.SetSrc(resInfo); } compassList_.SetPosition(213, 278); resInfo = OHOS::ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_COMPASS_LIST, COMPASS_IMAGE_BIN_PATH); if (resInfo) { compassList_.SetSrc(resInfo); } compassList_.SetStyle(STYLE_BORDER_WIDTH, 10); compassList_.SetStyle(STYLE_BORDER_OPA, 0x0); compassList_.SetViewId("compassList"); compassList_.SetTouchable(true); compassList_.SetOnClickListener(&TjdUiAppCompassPresenter::GetInstance()); compassDirection_.SetPosition(0, 154, 466, 66); compassDirection_.SetFont(TJD_VECTOR_FONT_FILENAME, 50); compassDirection_.SetViewId(COMPASS_SHOW_DIRECTION_ID); compassDirection_.SetText("N"); compassDirection_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); compassDirection_.SetStyle(STYLE_TEXT_COLOR, Color::Black().full); compassAzimuth_.SetPosition(0, 215, 466, 66); compassAzimuth_.SetFont(TJD_VECTOR_FONT_FILENAME, 50); compassAzimuth_.SetText("~29°"); compassAzimuth_.SetViewId(COMPASS_SHOW_AZIMUTH_ID); compassAzimuth_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); compassAzimuth_.SetStyle(STYLE_TEXT_COLOR, Color::Black().full); // g_CompassShowTimerId = osTimerNew((osTimerFunc_t)CompassShowTimerFunc, osTimerPeriodic, NULL, NULL); callback_ = new ShowViewAnimatorCallback(&compassBg_, &compassDirection_, &compassAzimuth_); animator_ = new OHOS::Animator(callback_, nullptr, 100, 1); Add(&compassBg_); Add(&compassPoint_); Add(&compassFg_); Add(&compassList_); Add(&compassDirection_); Add(&compassAzimuth_); } CompassShowView::~CompassShowView() { if (callback_) { delete callback_; callback_ = nullptr; } if (animator_) { animator_->Stop(); delete animator_; animator_ = nullptr; } if (dataAnimator_) { dataAnimator_->Stop(); delete dataAnimator_; dataAnimator_ = nullptr; } RemoveAll(); } void CompassShowView::ShowView() { SetVisible(true); animator_->Start(); } void CompassShowView::HideView() { SetVisible(false); animator_->Stop(); TjdUiAppCompassModel::GetInstance()->OpenAutoScreenOff(); } #pragma endregion 指南针显示页面 #pragma region 指南针数据页面 void DataAnimatorCallback::Callback(OHOS::UIView *view) { TjdUiAppCompassModel::GetInstance()->CloseAutoScreenOff(100); if (TjdUiAppCompassModel::GetInstance()->GetAccuracy() < 3) { auto CompassView = TjdUiAppCompassView::GetInstance(); CompassView->ShowView(VIEW_COMPASS_CALIBRATION); dataAnimator_->Stop(); return; } radio = TjdUiAppCompassModel::GetInstance()->GetAzimuth(); roll = TjdUiAppCompassModel::GetInstance()->GetRoll(); point_->Rotate(radio, DATA_ANIMATOR_CENTER); if (radio > 22.5F && radio <= 67.5F) { // direction_->SetText("东北"); direction_->SetTextId(STR_ID_322); } else if (radio > 67.5F && radio <= 112.5F) { // direction_->SetText("东"); direction_->SetTextId(STR_ID_317); } else if (radio > 112.5F && radio <= 157.5F) { // direction_->SetText("东南"); direction_->SetTextId(STR_ID_321); } else if (radio > 157.5F && radio <= 202.5F) { // direction_->SetText("南"); direction_->SetTextId(STR_ID_318); } else if (radio > 202.5F && radio <= 247.5F) { // direction_->SetText("西南"); direction_->SetTextId(STR_ID_323); } else if (radio > 247.5F && radio <= 292.5F) { // direction_->SetText("西"); direction_->SetTextId(STR_ID_319); } else if (radio > 292.5F && radio <= 337.5F) { // direction_->SetText("西北"); direction_->SetTextId(STR_ID_324); } else { // direction_->SetText("北"); direction_->SetTextId(STR_ID_320); } memset(dataStr, 0, sizeof(dataStr)); sprintf(dataStr, "~%.1f°", radio); directionVal_->SetText(dataStr); memset(dataStr, 0, sizeof(dataStr)); sprintf(dataStr, "%.1f°", roll); slopeVal_->SetText(dataStr); // printf("radio:%f\n", radio); } CompassDataView::CompassDataView() { SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); SetStyle(STYLE_BACKGROUND_OPA, 0xff); SetOnDragListener(&TjdUiAppCompassPresenter::GetInstance()); direction_.SetPosition(75, 84, 126, 61); direction_.SetFont(TJD_VECTOR_FONT_FILENAME, 65); // direction_.SetText("东北"); direction_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); direction_.SetStyle(STYLE_TEXT_COLOR, 0xFF00B4FF); direction_.SetTextId(STR_ID_317); directionVal_.SetPosition(74, 169, 127, 36); directionVal_.SetFont(TJD_VECTOR_FONT_FILENAME, 50); directionVal_.SetText("~129°"); directionVal_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); slope_.SetPosition(75, 278, 66, 33); slope_.SetFont(TJD_VECTOR_FONT_FILENAME, 34); // slope_.SetText("斜度"); slope_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); slope_.SetStyle(STYLE_TEXT_COLOR, 0xFF00B4FF); slope_.SetTextId(STR_ID_316); slopeVal_.SetPosition(76, 333, 72, 36); slopeVal_.SetFont(TJD_VECTOR_FONT_FILENAME, 50); slopeVal_.SetText("30°"); slopeVal_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); pointBg_.SetPosition(224, 188); auto resInfo = OHOS::ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_COMPASS_SCALE, COMPASS_IMAGE_BIN_PATH); if (resInfo) { pointBg_.SetSrc(resInfo); } point_.SetPosition(283, 224); resInfo = OHOS::ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_COMPASS_DIRECTION, COMPASS_IMAGE_BIN_PATH); if (resInfo) { point_.SetSrc(resInfo); } callback_ = new DataAnimatorCallback(&point_, &direction_, &directionVal_, &slopeVal_); dataAnimator_ = new OHOS::Animator(callback_, nullptr, 100, 1); Add(&direction_); Add(&directionVal_); Add(&slope_); Add(&slopeVal_); Add(&pointBg_); Add(&point_); } CompassDataView::~CompassDataView() { if (callback_) { delete callback_; callback_ = nullptr; } if (dataAnimator_) { dataAnimator_->Stop(); delete dataAnimator_; dataAnimator_ = nullptr; } RemoveAll(); } void CompassDataView::ShowView() { SetVisible(true); dataAnimator_->Start(); TjdUiAppCompassModel::GetInstance()->CloseAutoScreenOff(0xffffffff); } void CompassDataView::HideView() { SetVisible(false); dataAnimator_->Stop(); TjdUiAppCompassModel::GetInstance()->OpenAutoScreenOff(); } #pragma endregion 指南针数据页面 } // namespace TJD