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

594 lines
20 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*----------------------------------------------------------------------------
* 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 <stdio.h>
#include <string.h>
#include <string>
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