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

2645 lines
101 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.

#include "TjdUiAppSportView.h"
#include "NativeAbility.h"
#include "TjdUiAppIds.h"
#include "TjdUiAppSportDrawGuiAPI.h"
#include "TjdUiAppSportModel.h"
#include "TjdUiAppSportPage.h"
#include "TjdUiMemManage.h"
#include "TjdUiMultiLanguageExt.h"
#include "TjdUiUtils.h"
#include "ble_api.h"
#include "color.h"
#include "common/image_cache_manager.h"
#include "graphic_service.h"
#include "los_typedef.h"
#include "service_sport.h"
#include "sql_fit.h"
#include "style.h"
#include "sys/stat.h"
#include "sys_config.h"
#include "ui_screennotify.h"
#include "wearable_log.h"
#include <cstdio>
#include <hr_api.h>
#include <iomanip>
#include <limits>
#include <service_hrsensor.h>
#include <stdio.h>
#include <string>
#include <unistd.h>
using namespace OHOS;
#define DEBUG 1
#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 {
#define TJD_FS_DIR_SPORT "/system/tjd_sport"
#define CONFIRM_CANCEL_RES_BIN_PATH TJD_IMAGE_PATH "img_confirm_cancel.bin"
#define SPORT_IMAGE_BIN_PATH TJD_IMAGE_PATH "img_sport.bin"
#define BATTERY_IMAGE_BIN_PATH TJD_IMAGE_PATH "img_sport_battery.bin"
#define SPORT_DATA_JSON_PATH "/system/tjd_sport/sport_data.json"
static uint32_t g_comeback_dial_interval = 5;
static uint32_t timerCount = 0;
static OHOS::GraphicTimer *sportingTimer_ = nullptr; // 运动进行中计时器
static OHOS::GraphicTimer *gpsTimer_ = nullptr; // GPS定位计时器
static TjdUiAppSportView *g_pv_AppSportView = nullptr;
static EndOfSportDataView *g_EndOfSportDataView = nullptr;
static CountDownView *g_pv_CountDownView = nullptr;
static SportingView *g_pv_SportingView = nullptr;
static EditSportView *g_pv_EditSportView = nullptr;
static SportList *g_pv_SportList = nullptr;
static GPSView *g_pv_GPSView = nullptr;
SportViewManager TjdUiAppSportView::currentViewIndex_ = VIEW_MANAGER_MAX;
SportViewManager TjdUiAppSportView::lastViewIndex_ = VIEW_MANAGER_MAX;
SportTypeIndex TjdUiAppSportView::currentIconIndex_ = SPORT_TYPE_01_OUTDOOR_RUNNING_INDEX;
int SportingView::lastTime = 0;
SportType SportingView::sportType = SPORT_TYPE_MAX;
SportingData_t lastSportingData; // 记录上一次的运动数据;
extern bool returnToDial;
const static int16_t CENTER_X = 233;
const static int16_t CENTER_Y = 233;
const static int16_t LABEL_X = 204; // label的x坐标
const static int16_t LABEL_Y = 156; // label的y坐标
const static int16_t RADIUS = 144;
const static int16_t STROKE_WIDTH = 22;
const static int16_t CIRCLE_BASE_WIDTH = 22;
const static uint32_t LIGHT_GREEN = 0xFF2d4d0a;
static const uint16_t LABEL_FONT_SIZE = 100;
static const uint16_t ANIMATE_TIME = 500;
static const uint16_t SECOND_TO_MINISECOND = 1000;
static const uint16_t CIRCLE_FADE_OUT = 200;
static const uint16_t DEGREES_PER_CIRCLE = 360;
static uint16_t GPS_CAVAS_WIDTH = 136;
static uint16_t GPS_CAVAS_HEIGHT = 160;
// clang-format off
bool SportUIScrollView::OnDragStartEvent(const OHOS::DragEvent &event)
{
if (TjdUiAppSportView::currentViewIndex_ != SPORT_LIST_VIEW) {
return true;
}
isOnStart_ = true;
return OHOS::UIScrollViewNested::OnDragStartEvent(event);
}
bool SportUIScrollView::OnDragEvent(const OHOS::DragEvent &event)
{
if (!isOnStart_) {
return true;
}
if (TjdUiAppSportView::currentViewIndex_ != SPORT_LIST_VIEW) {
return true;
}
return OHOS::UIScrollViewNested::OnDragEvent(event);
}
bool SportUIScrollView::OnDragEndEvent(const OHOS::DragEvent &event)
{
if (!isOnStart_) {
return true;
}
isOnStart_ = false;
if (TjdUiAppSportView::currentViewIndex_ != SPORT_LIST_VIEW) {
return true;
}
return OHOS::UIScrollViewNested::OnDragEndEvent(event);
}
#pragma region 主界面
TjdUiAppSportView::TjdUiAppSportView(){ static_print_info("==line[%d]==func[%s]\n", __LINE__, __func__); g_pv_AppSportView = this;}
TjdUiAppSportView::~TjdUiAppSportView(){ static_print_info("==line[%d]==func[%s]\n", __LINE__, __func__); g_pv_AppSportView = nullptr;}
TjdUiAppSportView *TjdUiAppSportView::GetInstance(void) { return g_pv_AppSportView; }
// clang-format on
bool SportViewOnClickedListener::OnClick(UIView &view, const ClickEvent &event)
{
auto sportingView = SportingView::GetInstance();
auto sportPresenter = TjdUiAppSportPresenter::GetInstance();
if (view.GetViewId() == "pauseOrContinueCheckBox_") {
if (static_cast<OHOS::UICheckBox *>(&view)->GetState() == OHOS::UICheckBox::UICheckBoxState::SELECTED) {
TjdUiAppSportModel::GetInstance()->SetIfSportSuspend(true);
sportingTimer_->Stop();
SportingData_t Data = TjdUiAppSportModel::GetInstance()->GetServiceSportData();
sportingView->SportingViewDateRefresh(Data);
// sportPresenter->SportingControlHandler(SportingAction::Stop, nullptr);
} else {
TjdUiAppSportModel::GetInstance()->SetIfSportSuspend(false);
sportingTimer_->Start();
SportingView::lastTime = HALTick::GetInstance().GetTime();
sportingView->ResetSwipeView();
// sportPresenter->SportingControlHandler(SportingAction::Start, nullptr);
}
} else if (view.GetViewId() == "NoDataConfirm_" || view.GetViewId() == "DataConfirm_") {
// if (view.GetViewId() == "DataConfirm_") {
// TjdUiAppSportModel::GetInstance()->RecordSportData();
// }
TjdUiAppSportView::GetInstance()->ShowTargetView(SportViewManager::SPORT_LIST_VIEW);
} else if (view.GetViewId() == "imgEnlarge_") {
if (GPS_CAVAS_HEIGHT >= 315 || GPS_CAVAS_WIDTH >= 251)
return true;
GPS_CAVAS_HEIGHT = GPS_CAVAS_HEIGHT * 1.16;
GPS_CAVAS_WIDTH = GPS_CAVAS_WIDTH * 1.16;
sportingView->GPSCanvasAutoCenter();
printf("OnClick viewId: %s,GPS_CAVAS_HEIGHT = %d,screenWidth = %d\n", view.GetViewId(), GPS_CAVAS_HEIGHT,
GPS_CAVAS_WIDTH);
} else if (view.GetViewId() == "imgShrink") {
if (GPS_CAVAS_HEIGHT <= 88 || GPS_CAVAS_WIDTH <= 69)
return true;
GPS_CAVAS_HEIGHT = GPS_CAVAS_HEIGHT * 0.84;
GPS_CAVAS_WIDTH = GPS_CAVAS_WIDTH * 0.84;
sportingView->GPSCanvasAutoCenter();
printf("OnClick viewId: %s,GPS_CAVAS_HEIGHT = %d,screenWidth = %d\n", view.GetViewId(), GPS_CAVAS_HEIGHT,
GPS_CAVAS_WIDTH);
}
return true;
}
void TjdUiAppSportView::OnStart()
{
static_print_info("TjdUiAppSportView::OnStart()");
OHOS::FocusManager::GetInstance()->ClearFocus();
if (access(TJD_FS_DIR_SPORT, 0) != 0) {
mkdir(TJD_FS_DIR_SPORT, 0777);
static_print_debug("mkdir /system/tjd_sport dirent success");
}
TjdUiAppSportModel::GetInstance()->SearchAndRecordFilepath(); // 读取配置文件,并记录文件路径
OHOS::ImageCacheManager::GetInstance().LoadAllInMultiRes(SPORT_IMAGE_BIN_PATH);
if (access(SPORT_DATA_JSON_PATH, F_OK) != 0)
TjdUiAppSportModel::GetInstance()->CreateJsonAndSaveToFile(g_pv_Sport, SPORT_MAX_INDEX);
SportInfo *jsonSportInfo = TjdUiAppSportModel::GetInstance()->ReadFileAndTransformToJson();
SportDataInit();
InitSportList(jsonSportInfo);
InitEditSportView(jsonSportInfo);
free(jsonSportInfo);
if (mainView_ == nullptr) {
mainView_ = new SportUIScrollView();
}
mainView_->SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION);
// mainView_->SetOnDragListener(TjdUiAppSportPresenter::GetInstance());
AddViewToRootContainer(mainView_);
}
void TjdUiAppSportView::SportDataInit(void)
{
for (auto &goal : g_pv_SportGoal) {
goal.sportGoal = std::string(FontGlobalManager::GetInstance()->GetText(STR_ID_573));
goal.heartRateRemindGoal = std::string(FontGlobalManager::GetInstance()->GetText(STR_ID_217));
goal.timeRemindGoal = std::string(FontGlobalManager::GetInstance()->GetText(STR_ID_220));
goal.distRemindGoal = std::string(FontGlobalManager::GetInstance()->GetText(STR_ID_225));
}
}
void TjdUiAppSportView::OnStop()
{
OHOS::FocusManager::GetInstance()->ClearFocus();
static_print_info("TjdUiAppSportView==line[%d]==func[%s]\n", __LINE__, __func__);
OHOS::RootView::GetInstance()->Remove(mainView_);
if (editItemList_) {
delete editItemList_;
editItemList_ = nullptr;
}
if (sportItemList_) {
delete sportItemList_;
sportItemList_ = nullptr;
}
if (mainView_ != nullptr) {
mainView_->RemoveAll();
delete mainView_;
mainView_ = nullptr;
}
for (int i = 1; i < VIEW_MANAGER_MAX; ++i) {
if (viewManager_[i] != nullptr) {
viewManager_[i]->RemoveAll();
delete viewManager_[i];
viewManager_[i] = nullptr;
}
}
if (sportItemList_ != nullptr) {
delete sportItemList_;
sportItemList_ = nullptr;
}
for (int i = 0; i < SPORT_MAX_INDEX; ++i) {
if (imgItemInfo[i] != nullptr) {
delete imgItemInfo[i];
imgItemInfo[i] = nullptr;
}
}
if (sportingTimer_ != nullptr) {
sportingTimer_->Stop();
delete sportingTimer_;
sportingTimer_ = nullptr;
}
ImageCacheManager::GetInstance().UnloadAllInMultiRes(SPORT_IMAGE_BIN_PATH);
ImageCacheManager::GetInstance().UnloadAllInMultiRes(BATTERY_IMAGE_BIN_PATH);
ImageCacheManager::GetInstance().UnloadAllInMultiRes(CONFIRM_CANCEL_RES_BIN_PATH);
}
void TjdUiAppSportView::InitSportList(SportInfo *sportInfo)
{
auto &image = OHOS::ImageCacheManager::GetInstance();
if (sportItemList_ == nullptr) {
sportItemList_ = new std::list<SportCaseInfo>();
}
sportItemList_->clear();
image.LoadAllInMultiRes(SPORT_IMAGE_BIN_PATH);
for (uint8_t i = 0; i < SPORT_MAX_INDEX; i++) {
hashMap[static_cast<uint8_t>(g_pv_EditItemInfo[i].index)] = i;
g_pv_Sport[i].state = sportInfo[i].state;
if (g_pv_Sport[i].state) {
imgItemInfo[i] = image.LoadOneInMultiRes(g_pv_Sport[i].imgIconResId, SPORT_IMAGE_BIN_PATH);
sportItemList_->push_back(
{g_pv_Sport[i].index, imgItemInfo[i], g_pv_Sport[i].sportTypeId, g_pv_Sport[i].goalId});
}
}
}
void TjdUiAppSportView::InitEditSportView(SportInfo *sportInfo)
{
auto &image = OHOS::ImageCacheManager::GetInstance();
if (editItemList_ == nullptr) {
editItemList_ = new std::list<EditItemInfo>();
}
editItemList_->clear();
image.LoadAllInMultiRes(SPORT_IMAGE_BIN_PATH);
for (uint8_t i = 0; i < MAX_SPORT_TYPE; i++) {
g_pv_EditItemInfo[hashMap[i]].state = sportInfo[i].state;
printf("hashMap find sport = %d, position = %d\n", i, hashMap[i]);
editItemInfo[i] = image.LoadOneInMultiRes(g_pv_EditItemInfo[i].iconId, SPORT_IMAGE_BIN_PATH);
editItemList_->push_back({g_pv_EditItemInfo[i].index, editItemInfo[i], g_pv_EditItemInfo[i].sportTypeId,
g_pv_EditItemInfo[i].state});
}
}
void TjdUiAppSportView::ChooseSportItem(SportTypeIndex iconIndex)
{
if (iconIndex < 0 || iconIndex >= SPORT_MAX_INDEX) {
return;
}
static_print_info("==line[%d]==func[%s]==iconIndex[[%d]]\n", __LINE__, __func__, iconIndex);
switch (iconIndex) {
case SPORT_TYPE_03_INDOOR_CYCLING_INDEX:
case SPORT_TYPE_11_CYCLING_INDEX:
case SPORT_TYPE_38_FRISBEE_INDEX:
tjd_driver_hr_api_get_ops()->sport_mode_set(RIDE_MODE);
break;
case SPORT_TYPE_13_STAIRCASE_INDEX:
case SPORT_TYPE_16_STEPPER_INDEX:
case SPORT_TYPE_17_STROLLER_INDEX:
case SPORT_TYPE_08_ELLIPTICAL_INDEX:
tjd_driver_hr_api_get_ops()->sport_mode_set(WALK_MODE);
break;
case SPORT_TYPE_50_SKIPPING_INDEX:
tjd_driver_hr_api_get_ops()->sport_mode_set(JUMP_MODE);
break;
case SPORT_TYPE_04_FOOTBALL_INDEX:
case SPORT_TYPE_05_BASKETBALL_INDEX:
case SPORT_TYPE_09_INDOOR_SWIMMI_INDEX:
case SPORT_TYPE_10_OUTDOOR_SWIMM_INDEX:
case SPORT_TYPE_12_ON_FOOT_INDEX:
case SPORT_TYPE_14_ROWING_MACHINE_INDEX:
case SPORT_TYPE_15_JUZHONG_INDEX:
case SPORT_TYPE_18_HITI_INDEX:
case SPORT_TYPE_19_GYMNASTICS_INDEX:
case SPORT_TYPE_20_GROUP_INDEX:
case SPORT_TYPE_23_INSTRUMENT_INDEX:
case SPORT_TYPE_24_TAEKWONDO_INDEX:
case SPORT_TYPE_25_BOXING_INDEX:
case SPORT_TYPE_26_FREE_COMBAT_INDEX:
case SPORT_TYPE_27_KARATE_INDEX:
case SPORT_TYPE_28_FENCING_INDEX:
case SPORT_TYPE_29_CORE_TRAINING_INDEX:
case SPORT_TYPE_30_KICKBOXING_INDEX:
case SPORT_TYPE_37_HULA_HOOP_INDEX:
case SPORT_TYPE_39_BADMINTON_INDEX:
case SPORT_TYPE_40_PING_PONG_INDEX:
case SPORT_TYPE_41_TENNIS_INDEX:
case SPORT_TYPE_44_VOLLEYBALL_INDEX:
case SPORT_TYPE_45_BASEBALL_INDEX:
case SPORT_TYPE_46_RUGBY_INDEX:
case SPORT_TYPE_47_HOCKEY_INDEX:
case SPORT_TYPE_52_SAILBOAT_INDEX:
case SPORT_TYPE_53_SURFING_INDEX:
case SPORT_TYPE_56_CANOEING_INDEX:
tjd_driver_hr_api_get_ops()->sport_mode_set(HIGH_POW_MODE);
default:
break;
}
ShowTargetView(COUNT_DOWN_VIEW, iconIndex);
}
void TjdUiAppSportView::ShowTargetView(SportViewManager showIndex)
{
if (showIndex < 0 || showIndex >= VIEW_MANAGER_MAX) {
return;
}
InitTargetView(showIndex, SPORT_MAX_INDEX, 0);
if (currentViewIndex_ >= 0 && currentViewIndex_ < SportViewManager::VIEW_MANAGER_MAX &&
viewManager_[currentViewIndex_] != nullptr && showIndex != currentViewIndex_) {
viewManager_[currentViewIndex_]->HideView();
}
if (viewManager_[showIndex] != nullptr) {
viewManager_[showIndex]->ShowView();
}
currentViewIndex_ = showIndex;
}
void TjdUiAppSportView::ShowTargetView(SportViewManager showIndex, uint8_t touchIndex)
{
if (showIndex < 0 || showIndex >= VIEW_MANAGER_MAX) {
return;
}
InitTargetView(showIndex, SPORT_MAX_INDEX, touchIndex);
if (currentViewIndex_ >= 0 && currentViewIndex_ < SportViewManager::VIEW_MANAGER_MAX &&
viewManager_[currentViewIndex_] != nullptr) {
viewManager_[currentViewIndex_]->HideView();
}
if (viewManager_[showIndex] != nullptr) {
viewManager_[showIndex]->ShowView();
}
currentViewIndex_ = showIndex;
}
void TjdUiAppSportView::ShowTargetView(SportViewManager showIndex, SportTypeIndex iconIndex)
{
static_print_info("if coming here, showIndex = %d, iconIndex = %d\n", showIndex, iconIndex);
if (showIndex < 0 || showIndex >= VIEW_MANAGER_MAX) {
return;
}
switch (iconIndex) {
case SPORT_TYPE_01_OUTDOOR_RUNNING_INDEX:
case SPORT_TYPE_02_OUTDOOR_WALKING_INDEX:
case SPORT_TYPE_04_FOOTBALL_INDEX:
case SPORT_TYPE_05_BASKETBALL_INDEX:
case SPORT_TYPE_12_ON_FOOT_INDEX:
case SPORT_TYPE_13_STAIRCASE_INDEX:
SportingView::sportType = SPORT_TYPE_1;
showIndex = GPS_VIEW;
TjdUiAppSportModel::GetInstance()->SetSportType(SPORT_TYPE_1);
break;
case SPORT_TYPE_09_INDOOR_SWIMMI_INDEX:
case SPORT_TYPE_10_OUTDOOR_SWIMM_INDEX:
case SPORT_TYPE_11_CYCLING_INDEX:
case SPORT_TYPE_51_RIDING_INDEX ... SPORT_TYPE_57_MOTORBOAT_INDEX:
SportingView::sportType = SPORT_TYPE_2;
showIndex = GPS_VIEW;
TjdUiAppSportModel::GetInstance()->SetSportType(SPORT_TYPE_2);
break;
default:
SportingView::sportType = SPORT_TYPE_3;
showIndex = COUNT_DOWN_VIEW;
TjdUiAppSportModel::GetInstance()->SportHeartRateControlHandler(SportingAction::Start, nullptr);
TjdUiAppSportModel::GetInstance()->SetSportType(SPORT_TYPE_3);
break;
}
InitTargetView(showIndex, iconIndex, iconIndex);
if (currentViewIndex_ >= 0 && currentViewIndex_ < SportViewManager::VIEW_MANAGER_MAX &&
viewManager_[currentViewIndex_] != nullptr) {
viewManager_[currentViewIndex_]->HideView();
}
if (viewManager_[showIndex] != nullptr) {
viewManager_[showIndex]->ShowView();
}
currentViewIndex_ = showIndex;
currentIconIndex_ = iconIndex;
}
void TjdUiAppSportView::InitTargetView(SportViewManager index, SportTypeIndex iconIndex, uint8_t touchIndex)
{
if (viewManager_[index] != nullptr) {
return;
}
// clang-format off
switch (index) {
case SPORT_LIST_VIEW: viewManager_[index] = new SportList(); break;
case COUNT_DOWN_VIEW: viewManager_[index] = new CountDownView(); break;
case GPS_VIEW: viewManager_[index] = new GPSView(iconIndex); break;
case SPORTING_VIEW: viewManager_[index] = new SportingView(); break;
case SPORT_END_NODATA_VIEW: viewManager_[index] = new EndOfSportNoDataView(); break;
case SPORT_END_DATA_VIEW: viewManager_[index] = new EndOfSportDataView(); break;
case SPORT_GOAL_SELECT_VIEW: viewManager_[index] = new SportGoalSelectView(); break;
case SPORT_GOAL_DISTANCES_VIEW ... SPORT_GOAL_FREE_TRAINING_VIEW:
viewManager_[index] = new CommonViewGoalPage(static_cast<GoalSelectView>(touchIndex));
break;
case DISTANCE_GOAL_SELECT_VIEW: viewManager_[index] = new DistnaceGoalSelectView(); break;
case TIME_GOAL_SELECT_VIEW: viewManager_[index] = new TimeGoalSelectView(); break;
case CALORIES_GOAL_SELECT_VIEW: viewManager_[index] = new CaloriesGoalSelectView(); break;
case SPORT_REMIND_SELECT_VIEW:
viewManager_[index] = new RemindGoalListView(); break;
case HEART_RATE_PICK_VIEW: viewManager_[index] = new HeartRatePickView(); break;
case TIME_PICK_VIEW: viewManager_[index] = new TimeRemindPickView(); break;
case DISTANCE_PICK_VIEW: viewManager_[index] = new DistanceRemindPickView(); break;
case SPORT_EDIT_VIEW: viewManager_[index] = new EditSportView(); break;
// case SPORT_FINISH_REMIND_VIEW: viewManager_[index] = new SportFinishRemindView(); break;
default: break;
}
// clang-format on
if (viewManager_[index] == nullptr) {
return;
}
viewManager_[index]->SetPosition(0, 0);
viewManager_[index]->SetVisible(false);
mainView_->Add(viewManager_[index]);
}
Time TjdUiAppSportView::GetCurrentTime(const char *timeStr)
{
std::string timeString = timeStr;
Time curTime;
size_t firstColonPos = timeString.find(':');
if (firstColonPos != std::string::npos) {
size_t secondColonPos = timeString.find(':', firstColonPos + 1);
if (secondColonPos != std::string::npos) {
std::string hoursStr = timeString.substr(0, firstColonPos);
std::string minutesStr = timeString.substr(firstColonPos + 1, secondColonPos - firstColonPos - 1);
std::string secondsStr = timeString.substr(secondColonPos + 1);
curTime.hours = std::stoi(hoursStr);
curTime.minutes = std::stoi(minutesStr);
curTime.seconds = std::stoi(secondsStr);
return curTime;
}
}
return {0, 0, 0};
}
#pragma endregion
#pragma region 运动列表
#pragma region == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
SportList::SportList()
{
SetRotateEnable(*this);
g_pv_SportList = this;
SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION);
SetStyle(STYLE_BACKGROUND_OPA, 0);
if (OHOS::PageTransitionMgr::GetInstance().GetTopSlideBackImage() == nullptr) {
SetOnDragListener(TjdUiAppSportPresenter::GetInstance());
}
if (listlTitle_ == nullptr) {
listlTitle_ = new UILabelExt();
}
// InitLabelHorCenter(*listlTitle_, 28, 17, 466, "运动");
listlTitle_->SetFont(TJD_VECTOR_FONT_FILENAME, 28);
listlTitle_->SetTextId(STR_ID_05);
// listlTitle_->SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT);
listlTitle_->SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_TOP);
listlTitle_->SetPosition(0, 17, 466, 100);
editBackground_.SetPosition(18, 60, 430, 160);
auto imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_BJ_EDIT, SPORT_IMAGE_BIN_PATH);
imgBackground_.SetPosition(0, 0, 430, 80);
if (imgInfo != nullptr) {
imgBackground_.SetSrc(imgInfo);
}
imgBackground_.SetTouchable(true);
imgBackground_.SetViewId("sport_list_edit");
imgBackground_.SetOnClickListener(TjdUiAppSportPresenter::GetInstance());
editBackground_.Add(&imgBackground_);
// InitLabelHorCenter(*listlTitle_, 28, 17, 466, "运动");
lbEdit_.SetFont(TJD_VECTOR_FONT_FILENAME, 32);
lbEdit_.SetTextId(STR_ID_207);
lbEdit_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_MARQUEE);
lbEdit_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
lbEdit_.SetPosition(150, 0, 130, 80);
editBackground_.Add(&lbEdit_);
auto sportListItemInfo_ = TjdUiAppSportView::GetInstance()->GetSportItemList();
sportAdapterPtr_ = new TjdUITransformListGroupAdapter<SportCaseInfo, SportCaseItemView, std::list<SportCaseInfo>>(
*sportListItemInfo_);
sportListView_ = new TjdUITransformListGroup(sportAdapterPtr_);
sportListView_->AddCustomView(listlTitle_, TjdUITransformListGroup::CustomViewPos::TOP);
sportListView_->AddCustomView(&editBackground_, TjdUITransformListGroup::CustomViewPos::BOTTOM);
Add(sportListView_);
// Add(listlTitle_);
// Add(&editBackground_);
// Add(&editLabel_);
// Add(&listBackground_);
}
SportList *SportList::GetInstance() { return g_pv_SportList; }
void SportList::ShowView()
{
OHOS::FocusManager::GetInstance()->ClearFocus();
sportListView_->RequestFocus();
sportListView_->RefreshList();
// Invalidate();
SetVisible(true);
tjd_driver_hr_api_get_ops()->sport_mode_set(NORMAL_MODE);
if (tjd_service_hrs_get_ops()->hrs_get_service_id() == HR_SERVICE_UI_SPORT) {
tjd_service_hrs_get_ops()->close();
}
}
void SportList::SetListTitleVisible(bool visible)
{
if (visible)
listlTitle_->SetVisible(true);
else
listlTitle_->SetVisible(false);
}
SportList::~SportList()
{
static_print_info("SportList==line[%d]==func[%s]\n", __LINE__, __func__);
RemoveAll();
g_pv_SportList = nullptr;
if (sportListView_ != nullptr) {
sportListView_->RemoveAll();
delete sportListView_;
sportListView_ = nullptr;
}
if (sportAdapterPtr_ != nullptr) {
delete sportAdapterPtr_;
sportAdapterPtr_ = nullptr;
}
if (listlTitle_ != nullptr) {
delete listlTitle_;
listlTitle_ = nullptr;
}
}
#pragma endregion
#pragma region 倒计时界面
void TJD::CountdownAnimatorCallback::Callback(UIView *view)
{
switch (stage_) {
case countStage::STAGE_GRADUAL_CIRCLE: {
GradualCircle();
break;
}
case countStage::STAGE_COUNTING_DOWN: {
CountingDown();
break;
}
case countStage::STAGE_FADE_OUT: {
CountDownView::GetInstance()->GetCountdownAnimator()->Stop();
TjdUiAppSportView::GetInstance()->ShowTargetView(SPORTING_VIEW);
sportingTimer_->Start();
SportingView::lastTime = HALTick::GetInstance().GetTime();
// TjdUiAppSportPresenter::GetInstance()->SportingControlHandler(SportingAction::Start, nullptr);
CircleFadeOut();
break;
}
default:
break;
}
}
void CountdownAnimatorCallback::CircleFadeOut()
{
uint32_t diffTime = HALTick::GetInstance().GetTime() - lastTime_;
if (diffTime < idleTime_) {
return;
}
canvas_->Clear();
/* Calculate stroke width */
uint32_t curTime = diffTime - idleTime_;
uint16_t width;
if (curTime >= CIRCLE_FADE_OUT) {
curTime = CIRCLE_FADE_OUT;
stage_ = countStage::STAGE_NONE;
}
width = EasingEquation::QuadEaseInOut(STROKE_WIDTH, CIRCLE_BASE_WIDTH, curTime, CIRCLE_FADE_OUT);
/* Draw circle */
Point center = {CENTER_X, CENTER_Y};
PaintExt paint;
paint.SetStyle(Paint::PaintStyle::STROKE_STYLE);
paint.SetCapType(CAP_ROUND);
paint.SetAntialiased(true);
paint.SetStrokeColor(Color::GetColorFromRGB(0x94, 0xFF, 0x22));
paint.SetStrokeWidth(width);
canvas_->DrawCircle(center, RADIUS, paint);
uint16_t opa = OPA_OPAQUE * width / STROKE_WIDTH;
if (stage_ == countStage::STAGE_NONE) {
opa = OPA_TRANSPARENT;
}
label_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 100);
label_->SetStyle(STYLE_TEXT_OPA, opa);
}
void CountdownAnimatorCallback::UpdateLable(uint32_t curTime)
{
char buf[2] = {0}; // 2: buffer length
uint16_t fontSize;
uint16_t opa;
if (curTime < ANIMATE_TIME / 2) { // 2: half time
fontSize = LABEL_FONT_SIZE - LABEL_FONT_SIZE * curTime * 2 / ANIMATE_TIME; // 2: half time
opa = OPA_OPAQUE * fontSize / LABEL_FONT_SIZE;
} else {
fontSize = LABEL_FONT_SIZE * curTime * 2 / ANIMATE_TIME - LABEL_FONT_SIZE; // 2: half time
opa = OPA_OPAQUE * fontSize / LABEL_FONT_SIZE;
if (updateText_) {
if (sprintf_s(buf, sizeof(buf), "%u", (endAngle_ + easeDegree_) / degreePerSecond_ - 1) < 0) {
return;
}
label_->SetText(buf);
updateText_ = false;
}
}
label_->SetFont(TJD_VECTOR_FONT_FILENAME, 100);
label_->SetStyle(STYLE_TEXT_OPA, opa);
}
void CountdownAnimatorCallback::UpdatePath(int16_t start, int16_t end, bool needDrawCircle)
{
Point center = {CENTER_X, CENTER_Y};
ColorType lightGreen;
lightGreen.full = LIGHT_GREEN;
PaintExt paint;
paint.SetStyle(Paint::PaintStyle::STROKE_STYLE);
paint.SetStrokeWidth(STROKE_WIDTH);
paint.SetCapType(CAP_ROUND);
paint.SetAntialiased(true);
paint.SetStrokeColor(lightGreen);
canvas_->Clear();
if (needDrawCircle) {
canvas_->DrawCircle(center, RADIUS, paint);
}
if (start != end) {
paint.SetStrokeColor(Color::GetColorFromRGB(0x94, 0xFF, 0x22));
if (end - start == DEGREES_PER_CIRCLE) {
canvas_->DrawCircle(center, RADIUS, paint);
} else {
canvas_->DrawArc(center, RADIUS, start, end, paint);
}
}
}
void CountdownAnimatorCallback::CountingDown()
{
uint32_t diffTime = HALTick::GetInstance().GetTime() - lastTime_;
if (diffTime >= SECOND_TO_MINISECOND) {
lastTime_ = HALTick::GetInstance().GetTime();
if (endAngle_ == DEGREES_PER_CIRCLE) {
firstArc_ = true;
} else {
firstArc_ = false;
}
UpdatePath(0, endAngle_, true);
UpdateLable(0);
if (endAngle_ == 0) {
stage_ = countStage::STAGE_FADE_OUT;
idleTime_ = SECOND_TO_MINISECOND - CIRCLE_FADE_OUT;
return;
}
easeDegree_ = degreePerSecond_;
endAngle_ -= degreePerSecond_;
if (endAngle_ <= surplusDegree) {
endAngle_ = 0;
easeDegree_ += surplusDegree;
}
updateText_ = true;
} else if (diffTime + 10 >= idleTime_) {
uint32_t curTime = diffTime - idleTime_;
int16_t arcCurr = EasingEquation::QuadEaseInOut(0, easeDegree_, curTime, ANIMATE_TIME);
UpdatePath(0, endAngle_ + easeDegree_ - arcCurr, true);
UpdateLable(curTime);
}
}
void CountdownAnimatorCallback::GradualCircle()
{
uint32_t diffTime = HALTick::GetInstance().GetTime() - lastTime_;
if (diffTime >= SECOND_TO_MINISECOND) {
stage_ = countStage::STAGE_COUNTING_DOWN;
idleTime_ = SECOND_TO_MINISECOND - ANIMATE_TIME;
} else if (diffTime >= idleTime_) {
uint32_t curTime = diffTime - idleTime_;
int16_t arcCurr =
EasingEquation::QuadEaseInOut(0, DEGREES_PER_CIRCLE, curTime, SECOND_TO_MINISECOND - idleTime_);
}
}
void CountdownAnimatorCallback::SetInfo(UILabel *label, int counts)
{
counts_ = counts;
label_ = label;
}
void CountdownAnimatorCallback::NotifyStart()
{
stage_ = countStage::STAGE_GRADUAL_CIRCLE;
endAngle_ = DEGREES_PER_CIRCLE;
idleTime_ = 200; // 200: idle time for first circle animate
degreePerSecond_ = DEGREES_PER_CIRCLE / counts_;
surplusDegree = DEGREES_PER_CIRCLE - degreePerSecond_ * counts_;
label_->SetText("3");
label_->SetFont(TJD_VECTOR_FONT_FILENAME, 100);
}
void CountDownView::ShowView()
{
SportTypeIndex iconIndex = TjdUiAppSportView::currentIconIndex_;
CountDownViewRefresh(iconIndex);
SetVisible(true);
}
CountDownView::CountDownView()
{
static_print_info("CountDownView=======\n");
g_pv_CountDownView = this;
SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION);
SetStyle(STYLE_BACKGROUND_OPA, 0);
SetDraggable(true);
SetOnDragListener(TjdUiAppSportPresenter::GetInstance());
imgSport_.SetPosition(188, 0);
auto imgInfo =
ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_01_OUTDOOR_RUNNING, SPORT_IMAGE_BIN_PATH);
imgSport_.SetSrc(imgInfo);
if (canvas_ == nullptr) {
canvas_ = new UICanvasExt();
}
canvas_->SetPosition(0, 0, 466, 466);
canvas_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);
label_.SetPosition(LABEL_X, LABEL_Y, 44, 74);
label_.SetLineBreakMode(UILabel::LINE_BREAK_ADAPT);
label_.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
PaintExt paint;
paint.SetStyle(Paint::PaintStyle::STROKE_STYLE);
paint.SetStrokeWidth(CIRCLE_BASE_WIDTH);
paint.SetAntialiased(true);
paint.SetStrokeColor(Color::GetColorFromRGB(0x2d, 0x4d, 0x0a));
canvas_->DrawCircle({CENTER_X, CENTER_Y}, RADIUS, paint);
callBack_ = new TJD::CountdownAnimatorCallback(canvas_);
countdownAnimator_ = new Animator(callBack_, canvas_, 0, true);
callBack_->SetInfo(&label_, 3); // 5: countdown numbers
Add(&imgSport_);
Add(canvas_);
Add(&label_);
}
void CountDownView::HideView()
{
lastSportingData = TjdUiAppSportModel::GetInstance()->GetServiceSportData();
countdownAnimator_->Stop();
SetVisible(false);
}
CountDownView::~CountDownView()
{
static_print_info("CountDownView==line[%d]==func[%s]\n", __LINE__, __func__);
g_pv_CountDownView = nullptr;
RemoveAll();
if (canvas_ != nullptr) {
delete canvas_;
canvas_ = nullptr;
}
if (countdownAnimator_ != nullptr) {
countdownAnimator_->Stop();
delete countdownAnimator_;
countdownAnimator_ = nullptr;
}
if (callBack_ != nullptr) {
delete callBack_;
callBack_ = nullptr;
}
}
CountDownView *CountDownView::GetInstance() { return g_pv_CountDownView; }
void CountDownView::CountDownViewRefresh(SportTypeIndex index)
{
auto iconRes =
OHOS::ImageCacheManager::GetInstance().LoadOneInMultiRes(g_pv_Sport[index].imgIconResId, SPORT_IMAGE_BIN_PATH);
Vector2<float> scale = {0.6, 0.6};
Vector2<float> pivot = {30, 30};
imgSport_.SetSrc(iconRes);
imgSport_.Scale(scale, pivot);
imgSport_.Invalidate();
countdownAnimator_->Start();
callBack_->NotifyStart();
}
#pragma region GPS定位界面
static void gpsTimerCallBack(void *arg)
{
static_print_info("gpsTimerCallBack\n");
static uint8_t count = 0;
if (count == 180) { // <20>ȴ<EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD>
count = 0;
gpsTimer_->Stop();
TjdUiAppSportModel::GetInstance()->GPSServiceClose();
}
static_print_info("TjdUiAppSportModel::GetInstance()->GPSGettingLocationSuccess() = %d\n",
TjdUiAppSportModel::GetInstance()->GPSGetData().valid);
if (TjdUiAppSportModel::GetInstance()->GPSGetData().valid) {
GraphicService::GetInstance()->PostGraphicEvent(
std::bind([](void *arg) { GPSView::GetInstance()->GPSPossitionSuccessRefresh(); }, arg));
}
GraphicService::GetInstance()->PostGraphicEvent(
std::bind([](void *arg) { GPSView::GetInstance()->GPSViewDataRefresh(); }, arg));
count++;
}
bool GPSIconOnClickListener::OnClick(UIView &view, const ClickEvent &event)
{
static_print_info("GPSIconOnClickListener::OnClick\n");
auto sportView = TjdUiAppSportView::GetInstance();
sportView->ShowTargetView(COUNT_DOWN_VIEW);
return true;
}
// bool GPSOnkeyActListener::OnKeyAct(OHOS::UIView &view, const OHOS::KeyEvent &event)
// {
// static_print_info("GPSOnkeyActListener::OnKeyAct\n");
// if (event.GetKeyId() == 4165 ) {
// if (event.GetState() == OHOS::InputDevice::STATE_RELEASE) {
// TjdUiAppSportView::GetInstance()->ShowTargetView(COUNT_DOWN_VIEW);
// }
// }
// return false;
// }
Signal::Signal()
{
SetPosition(0, 0, 22, 26);
signalLow_.SetPosition(0, 14, 4, 12);
signalLow_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0000);
signalLow_.SetStyle(STYLE_BORDER_RADIUS, 2);
signalMiddle_.SetPosition(9, 8, 4, 18);
signalMiddle_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0000);
signalMiddle_.SetStyle(STYLE_BORDER_RADIUS, 2);
signalHigh_.SetPosition(18, 0, 4, 26);
signalHigh_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0000);
signalHigh_.SetStyle(STYLE_BORDER_RADIUS, 2);
Add(&signalLow_);
Add(&signalMiddle_);
Add(&signalHigh_);
}
void Signal::RefreshSignal(int signal)
{
//先这样假定信号强度
switch (signal) {
case 0 ... 2:
signalLow_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFea3d35);
signalMiddle_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFea3d35);
signalHigh_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFea3d35);
break;
case 3:
signalLow_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFea3d35);
signalMiddle_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFea3d35);
signalHigh_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFFFFFFF);
break;
case 4:
signalLow_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFea3d35);
signalMiddle_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFFFFFFF);
signalHigh_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFFFFFFF);
break;
case 5 ... 15:
signalLow_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0fbd55);
signalMiddle_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFFFFFFF);
signalHigh_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFFFFFFF);
break;
case 16 ... 31:
signalLow_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0fbd55);
signalMiddle_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0fbd55);
signalHigh_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFFFFFFF);
break;
case 32 ... 999:
signalLow_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0fbd55);
signalMiddle_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0fbd55);
signalHigh_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0fbd55);
break;
break;
default:
break;
}
signalLow_.Invalidate();
signalMiddle_.Invalidate();
signalHigh_.Invalidate();
}
GPSView::GPSView(SportTypeIndex iconIndex)
{
static_print_info("GPSView=======\n");
g_pv_GPSView = this;
SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION);
SetStyle(STYLE_BACKGROUND_OPA, 0);
SetDraggable(true);
SetOnDragListener(TjdUiAppSportPresenter::GetInstance());
ImageInfo *imgInfo =
ImageCacheManager::GetInstance().LoadOneInMultiRes(g_pv_Sport[iconIndex].imgIconResId, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&SportIcon_, 158, 156, "SportIcon_", imgInfo);
const Vector2<float> &scale = {1.6, 1.6};
Vector2<float> pivot = {50, 50};
SportIcon_.Scale(scale, pivot);
SportIcon_.SetStyle(STYLE_IMAGE_OPA, 76);
SportIcon_.Invalidate();
SportIcon_.SetTouchable(true);
SportIcon_.SetOnClickListener(&GPSIconOnClickListener_);
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_BATTERY_BAT_A, BATTERY_IMAGE_BIN_PATH);
UiDrawImage(&imgBat_, 166, 55, imgInfo);
InitLabel(batValue_, 32, 238, 48, "100%", TJD_DIN_MEDIUM_FONT_FILENAME);
InitLabel(GPSTitle_, 34, 30, 208, "GPS");
// imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_GPS_UNSUCCESS, SPORT_IMAGE_BIN_PATH);
// UiDrawImage(&signal_, 109, 218, imgInfo);
signal_.SetPosition(109, 218);
signal_.RefreshSignal(0);
InitLabel(hrValue_, 32, 350, 236, "--", TJD_DIN_MEDIUM_FONT_FILENAME);
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_GPS_HR, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&hrIcon_, 350, 184, imgInfo);
// InitLabelHorCenter(GPSTip_, 34, 312, 466, "定位中...");
GPSTip_.SetFont(TJD_VECTOR_FONT_FILENAME, 34);
GPSTip_.SetTextId(STR_ID_190);
GPSTip_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_MARQUEE);
GPSTip_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
GPSTip_.SetPosition(0, 312, 466, 46);
// InitLabelHorCenter(GPSTip1_, 30, 367, 466, "请到空旷位置等待");
GPSTip1_.SetFont(TJD_VECTOR_FONT_FILENAME, 34);
GPSTip1_.SetTextId(STR_ID_191);
GPSTip1_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_WRAP);
GPSTip1_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
GPSTip1_.SetPosition(60, 367, 346, 46);
GPSTip1_.SetStyle(STYLE_TEXT_OPA, 0xff * 0.3);
if (gpsTimer_ == nullptr) {
gpsTimer_ = new OHOS::GraphicTimer(1000, gpsTimerCallBack, nullptr, true);
}
Add(&GPSTip_);
Add(&GPSTip1_);
Add(&GPSTitle_);
Add(&SportIcon_);
Add(&signal_);
Add(&hrIcon_);
Add(&hrValue_);
Add(&imgBat_);
Add(&batValue_);
}
void GPSView::ShowView()
{
auto model = TjdUiAppSportModel::GetInstance();
if (model == nullptr)
return;
signal_.RefreshSignal(0);
model->RegisterGnssChangedCB();
set_back_to_home_interval(60 * 3); // 运动进行中熄屏不允许返回主表盘
model->GPSServiceOpen();
model->SportHeartRateControlHandler(SportingAction::Start, nullptr);
SportTypeIndex iconIndex = TjdUiAppSportView::currentIconIndex_;
GPSViewRefresh(iconIndex);
GPSViewDataRefresh();
if (gpsTimer_ != nullptr)
gpsTimer_->Start();
SetVisible(true);
}
void GPSView::HideView()
{
auto model = TjdUiAppSportModel::GetInstance();
if (model == nullptr)
return;
model->UnregisterGnssChangedCB();
set_back_to_home_interval(5);
if (!model->GPSGetData().valid)
model->GPSServiceClose();
if (gpsTimer_ != nullptr)
gpsTimer_->Stop();
SetVisible(false);
}
GPSView *GPSView::GetInstance() { return g_pv_GPSView; }
GPSView::~GPSView()
{
static_print_info("GPSView==line[%d]==func[%s]\n", __LINE__, __func__);
g_pv_GPSView = nullptr;
if (gpsTimer_ != nullptr) {
gpsTimer_->Stop();
delete gpsTimer_;
gpsTimer_ = nullptr;
}
RemoveAll();
}
void GPSView::GPSViewRefresh(SportTypeIndex index)
{
auto iconRes =
OHOS::ImageCacheManager::GetInstance().LoadOneInMultiRes(g_pv_Sport[index].imgIconResId, SPORT_IMAGE_BIN_PATH);
Vector2<float> scale = {1.6, 1.6};
Vector2<float> pivot = {50, 50};
SportIcon_.SetSrc(iconRes);
SportIcon_.SetX(183);
SportIcon_.Scale(scale, pivot);
SportIcon_.SetStyle(STYLE_IMAGE_OPA, 76);
SportIcon_.Invalidate();
}
void GPSView::GPSViewDataRefresh(void)
{
auto model = TjdUiAppSportModel::GetInstance();
if (model == nullptr)
return;
if (model->GetCurHeartRateValue()) {
hrValue_.SetText(std::to_string(model->GetCurHeartRateValue()).c_str());
} else
hrValue_.SetText("--");
uint8_t battery = model->GetBatteryValue();
uint8_t bat_level = battery / 10;
signal_.RefreshSignal(model->GetMaxSnr());
auto imgInfo =
ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_BATTERY_BAT_0 + bat_level, BATTERY_IMAGE_BIN_PATH);
imgBat_.SetSrc(imgInfo);
batValue_.SetText((std::to_string(model->GetBatteryValue()) + std::string("%")).c_str());
}
void GPSView::GPSPossitionSuccessRefresh()
{
static_print_info("GPSPossitionSuccessRefresh\n");
SportIcon_.SetStyle(STYLE_IMAGE_OPA, 255);
SportIcon_.Invalidate();
// InitLabelHorCenter(GPSTip_, 34, 312, 466, "定位成功");
GPSTip_.SetFont(TJD_VECTOR_FONT_FILENAME, 34);
GPSTip_.SetTextId(STR_ID_192);
GPSTip_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_MARQUEE);
GPSTip_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
GPSTip_.SetPosition(0, 312, 466, 46);
// InitLabelHorCenter(GPSTip1_, 30, 367, 466, "点击右上按键开始");
GPSTip1_.SetFont(TJD_VECTOR_FONT_FILENAME, 34);
GPSTip1_.SetTextId(STR_ID_192);
GPSTip1_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_MARQUEE);
GPSTip1_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
GPSTip1_.SetPosition(60, 367, 346, 46);
GPSTip1_.SetStyle(STYLE_TEXT_OPA, 0xff * 0.3);
// auto imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_GPS_SUCCESS, BATTERY_IMAGE_BIN_PATH);
// signal_.SetSrc(imgInfo);
}
#pragma endregion
#pragma region 运动进行中
ImgEndOnTouchListener::ImgEndOnTouchListener()
{
pressImgSrc_ = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_PRESS, SPORT_IMAGE_BIN_PATH);
releaseImgSrc_ = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_RELEASE, SPORT_IMAGE_BIN_PATH);
}
ImgEndOnTouchListener::~ImgEndOnTouchListener()
{
static_print_info("ImgEndOnTouchListener::Destory...");
if (pressImgSrc_ != nullptr) {
pressImgSrc_ = nullptr;
}
if (releaseImgSrc_ != nullptr) {
releaseImgSrc_ = nullptr;
}
};
bool ImgEndOnTouchListener::OnPress(UIView &view, const PressEvent &event)
{
SportingView::GetInstance()->imgEnd_.SetSrc(pressImgSrc_);
view.SetDragParentInstead(false);
if (SportingView::GetInstance()->animator_->GetState() == Animator::STOP)
SportingView::GetInstance()->animator_->Start();
return true;
}
bool ImgEndOnTouchListener::OnRelease(UIView &view, const ReleaseEvent &event)
{
auto sportingView = SportingView::GetInstance();
sportingView->imgEnd_.SetSrc(releaseImgSrc_);
SportingView::GetInstance()->animator_->Stop();
return true;
}
bool ImgEndOnTouchListener::OnCancel(OHOS::UIView &view, const OHOS::CancelEvent &event)
{
auto sportingView = SportingView::GetInstance();
sportingView->imgEnd_.SetSrc(releaseImgSrc_);
SportingView::GetInstance()->animator_->Stop();
return true;
}
///********************************************************************************************************************/
/// @brief :运动进行中主界面
///********************************************************************************************************************/
static char *str = nullptr;
static void TimerCallBack(void *arg)
{
static_print_info("TimerCallBack\n");
int curTime = HALTick::GetInstance().GetTime();
if (curTime - SportingView::lastTime >= 1000) {
GraphicService::GetInstance()->PostGraphicEvent(std::bind(
[](void *arg) {
if (timerCount == 0) // 60//临时调试
{
if (TjdUiAppSportModel::GetInstance()->SearchAndRecordFilepath().size() <= 14) {
str = (char *)TjdUiAppSportModel::GetInstance()
->RecordSportData(); // 当时间到达60秒时记录一次运动数据
} else {
std::vector<std::string> fileList =
TjdUiAppSportModel::GetInstance()->SearchAndRecordFilepath();
// 如果 fileList 达到最大数量,删除最旧的文件
if (fileList.size() >= 15) {
TjdUiAppSportModel::GetInstance()->RemoveFile((const char *)fileList[0].c_str());
fileList.erase(fileList.begin()); // 删除第一个元素
}
str = (char *)TjdUiAppSportModel::GetInstance()
->RecordSportData(); // 当时间到达60秒时记录一次运动数据
// 添加新的文件名
static_print_info("new file name = %s\n", str);
fileList.push_back(str);
}
}
if (timerCount > 0 && timerCount % 1 == 0) { // 临时调试
gnss_data_t gps_data = TjdUiAppSportModel::GetInstance()->GPSGetData();
TjdUiAppSportModel::GetInstance()->AddDataToArry(str, gps_data.latitude, gps_data.longitude);
TjdUiAppSportModel::GetInstance()->UpdateSportData(str);
// TjdUiAppSportModel::GetInstance()->RenameSportDataFile(str);
} else if (timerCount > 0) {
TjdUiAppSportModel::GetInstance()->UpdateSportData(str);
}
pthread_mutex_lock(&data_mutex);
SportingData_t curSportingData = TjdUiAppSportModel::GetInstance()->GetServiceSportData();
pthread_mutex_unlock(&data_mutex);
SportingView::GetInstance()->SportingViewDateRefresh(curSportingData);
timerCount++;
},
arg));
SportingView::lastTime = HALTick::GetInstance().GetTime();
}
}
SportingView::SportingView()
{
static_print_info("SportingMainView::SportingMainView");
g_pv_SportingView = this;
SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION);
SetDraggable(true);
SetOnDragListener(TjdUiAppSportPresenter::GetInstance());
auto iconIndex = TjdUiAppSportView::GetInstance()->currentIconIndex_;
// if (swipeGPSView_ == nullptr) {
// swipeGPSView_ = new UISwipeView(OHOS::UISwipeView::VERTICAL);
// }
// swipeGPSView_->SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION);
// swipeGPSView_->SetDragParentInstead(false);
// swipeGPSView_->SetOnSwipeListener(onSwipeListener_);
// swipeGPSView_->SetOnDragListener(OnDragListener_);
// swipeGPSView_->SetOnClickListener(onClickListener_);
// if (containerView_ == nullptr) {
// containerView_ = new UIViewGroup();
// }
// containerView_->SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION);
if (swipeMainView_ == nullptr) {
swipeMainView_ = new UISwipeView(OHOS::UISwipeView::HORIZONTAL);
}
swipeMainView_->SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION);
// swipeMainView_->SetOnSwipeListener(onSwipeListener_);
swipeMainView_->SetOnDragListener(OnDragListener_);
swipeMainView_->SetOnClickListener(onClickListener_);
#if 0
// swipeMainView_->Add(InitSportingPauseOrContinueView(&sportingPauseOrContinueView_));
// containerView_->Add(swipeGPSView_);
swipeMainView_->Add(InitSportingGPSView(&sportingGPSView_));
swipeMainView_->Add(swipeGPSView_);
swipeGPSView_->Add(InitsportingDataRecordView(&sportingDataRecordView_, iconIndex));
// swipeGPSView_->Add(InitSportingGPSView(&sportingGPSView_));
swipeGPSView_->Add(InitSportingPauseOrContinueView(&sportingPauseOrContinueView_));
#else
swipeMainView_->Add(InitSportingPauseOrContinueView(&sportingPauseOrContinueView_));
swipeMainView_->Add(InitsportingDataRecordView(&sportingDataRecordView_, iconIndex));
InitSportingGPSView(&sportingGPSView_);
#endif
// swipeGPSView_->SetOnSwipeListener(onSwipeListener_);
if (sportingTimer_ == nullptr) {
sportingTimer_ = new OHOS::GraphicTimer(250, TimerCallBack, nullptr, true);
}
Add(swipeMainView_);
}
static uint8_t gpsTrack = 0;
void SportingView::ShowView()
{
static_print_info("tjd_get_service_if_open = %d\n", tjd_get_service_if_open());
timerCount = 0;
g_comeback_dial_interval = get_back_to_home_interval();
set_back_to_home_interval(0xFFFFFFFF); // 运动进行中熄屏不允许返回主表盘
TjdUiAppSportModel::GetInstance()->SetSportEndRemindType(SPORT_MSG_TYPE_END_30_MIN_REMIND);
UIView *view = swipeMainView_->GetChildById("sportingGPSView");
if (static_cast<UIScrollView *>(view)) {
printf("view is not null\n");
if (SportingView::sportType == SPORT_TYPE_1 || SportingView::sportType == SPORT_TYPE_2)
ShowGPSTrackView(true);
else
HideGPSTrackView();
} else {
printf("view is null\n");
if (SportingView::sportType == SPORT_TYPE_1 || SportingView::sportType == SPORT_TYPE_2)
ShowGPSTrackView(false);
}
ResetSwipeView();
if (!TjdUiAppSportModel::GetInstance()->GPSGetData().valid) //运动开始时如果gps数据无效则关闭gps服务
{
printf("gps data invalid, close gps service\n");
// TjdUiAppSportModel::GetInstance()->GPSServiceClose();
TjdUiAppSportView::GetInstance()->SetGPState(false);
} else
TjdUiAppSportView::GetInstance()->SetGPState(true);
if (!tjd_get_service_if_open()) {
tjd_service_sport_open();
}
if (returnToDial) {
sportingTimer_->Start();
}
SportingViewRefresh();
ImageInfo *imgInfo =
ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_RELEASE, SPORT_IMAGE_BIN_PATH);
imgEnd_.SetSrc(imgInfo);
SetVisible(true);
}
void SportingView::HideView()
{
static_print_info("SportingMainView::HideView\n");
set_back_to_home_interval(g_comeback_dial_interval);
if (tjd_get_service_if_open()) {
tjd_service_sport_close();
}
sportingTimer_->Stop();
SetPauseOrContinueCheckBoxState(1);
if (!returnToDial) //如果回到主表盘则不关闭GPS、心率
{
auto model = TjdUiAppSportModel::GetInstance();
if (model == nullptr)
return;
model->GPSServiceClose(); // 关闭GPS服务
model->SportHeartRateControlHandler(SportingAction::Stop, nullptr);
}
SetVisible(false);
}
void SportingView::ShowGPSTrackView(bool exit)
{
gpsTrack = 0; //轨迹假数据
if (!exit)
swipeMainView_->Add(sportingGPSView_);
gpsCanvas_.Clear();
trajectory.clear();
gpsTrackTimer_->Start();
GPS_CAVAS_WIDTH = 214;
GPS_CAVAS_HEIGHT = 252;
gpsCanvas_.SetPosition(126, 107, GPS_CAVAS_WIDTH, GPS_CAVAS_HEIGHT);
if (TjdUiAppSportModel::GetInstance()->GPSGetData().valid)
lbState_.SetTextId(STR_ID_195);
else
lbState_.SetTextId(STR_ID_194);
}
void SportingView::HideGPSTrackView()
{
printf("HideGPSTrackView\n");
swipeMainView_->Remove(sportingGPSView_);
gpsTrackTimer_->Stop();
}
SportingView::~SportingView()
{
static_print_info("SportingMainView Destory=======\n");
RemoveAll();
if (!returnToDial) //如果回到主表盘则不关闭GPS、心率
{
auto model = TjdUiAppSportModel::GetInstance();
if (model == nullptr)
return;
model->GPSServiceClose(); // 关闭GPS服务
model->SportHeartRateControlHandler(SportingAction::Stop, nullptr);
}
if (stopAnimatorCallback_ != nullptr) {
delete stopAnimatorCallback_;
stopAnimatorCallback_ = nullptr;
}
if (animator_ != nullptr) {
animator_->Stop();
delete animator_;
animator_ = nullptr;
}
if (gpsTrackTimer_ != nullptr) {
gpsTrackTimer_->Stop();
delete gpsTrackTimer_;
gpsTrackTimer_ = nullptr;
}
if (trackAnimator_ != nullptr) {
trackAnimator_->Stop();
delete trackAnimator_;
trackAnimator_ = nullptr;
}
if (swipeMainView_ != nullptr) {
swipeMainView_->Remove(sportingDataRecordView_);
swipeMainView_->Remove(sportingPauseOrContinueView_);
swipeMainView_->Remove(sportingGPSView_);
delete swipeMainView_;
swipeMainView_ = nullptr;
}
if (imgEndOnTouchListener_ != nullptr) {
delete imgEndOnTouchListener_;
imgEndOnTouchListener_ = nullptr;
}
if (sportViewOnClickedListener_ != nullptr) {
delete sportViewOnClickedListener_;
sportViewOnClickedListener_ = nullptr;
}
if (sportingGPSView_) {
sportingGPSView_->RemoveAll();
delete sportingGPSView_;
sportingGPSView_ = nullptr;
}
if (sportingPauseOrContinueView_) {
sportingPauseOrContinueView_->RemoveAll();
delete sportingPauseOrContinueView_;
sportingPauseOrContinueView_ = nullptr;
}
if (sportingDataRecordView_) {
sportingDataRecordView_->RemoveAll();
delete sportingDataRecordView_;
sportingDataRecordView_ = nullptr;
}
if (sportingTimer_ != nullptr) {
sportingTimer_->Stop();
delete sportingTimer_;
sportingTimer_ = nullptr;
}
// if (onSwipeListener_ != nullptr) {
// delete onSwipeListener_;
// onSwipeListener_ = nullptr;
// }
// if (OnDragListener_ != nullptr) {
// delete OnDragListener_;
// OnDragListener_ = nullptr;
// }
if (onClickListener_ != nullptr) {
delete onClickListener_;
onClickListener_ = nullptr;
}
g_pv_SportingView = nullptr;
}
void SportingView::SportingViewDateRefresh(SportingData_t curSportingData)
{
auto sportView = TjdUiAppSportView::GetInstance();
auto lastSportingData_ = lastSportingData;
std::ostringstream sportTimeOss;
std::ostringstream oss;
std::ostringstream caloriesOss;
std::ostringstream distanceOss;
static_print_info("===curSportingData.distance=%d ==lastSportingData.distance%d===\n", curSportingData.distance,
lastSportingData_.distance);
// Time currentTime = sportView->GetCurrentTime(GetSportingRtcLabelText());
hours = curSportingData.exerciseDuration / 3600;
minutes = (curSportingData.exerciseDuration % 3600) / 60;
seconds = curSportingData.exerciseDuration % 60;
sportTimeOss << std::setw(2) << std::setfill('0') << hours << ":" << std::setw(2) << std::setfill('0') << minutes
<< ":" << std::setw(2) << std::setfill('0') << seconds;
SetSportingRtcLabelText(sportTimeOss.str().c_str());
if (curSportingData.heartRate)
heartRateLabel_.SetText(std::to_string(curSportingData.heartRate).c_str());
else
heartRateLabel_.SetText("---");
distance = curSportingData.distance/1000.0f;
calories = curSportingData.calories;
step = curSportingData.steps;
switch (curSportingData.heartRate) {
case 40 ... 138:
imgPoint_.Rotate(240, VIEW_CENTER);
break;
case 139 ... 150:
imgPoint_.Rotate(300, VIEW_CENTER);
break;
case 151 ... 162:
imgPoint_.Rotate(0, VIEW_CENTER);
break;
case 163 ... 174:
imgPoint_.Rotate(60, VIEW_CENTER);
break;
case 175 ... 200:
imgPoint_.Rotate(120, VIEW_CENTER);
break;
default:
imgPoint_.Rotate(0, VIEW_CENTER);
break;
}
oss << std::setw(5) << std::setfill('0') << step;
stepLabel_.SetText(oss.str().c_str());
caloriesOss << std::setw(4) << std::setfill('0') << calories;
caloriesLabel_.SetText(caloriesOss.str().c_str());
distanceOss << std::fixed << std::setprecision(2) << distance; // 设置固定小数点格式和一位小数
distanceLabel_.SetText(distanceOss.str().c_str());
static_print_info("===sportTimeOss=%s==%s=%s=%s=\n", sportTimeOss.str().c_str(), oss.str().c_str(),
caloriesOss.str().c_str(), distanceOss.str().c_str());
}
SportingView *SportingView::GetInstance() { return g_pv_SportingView; }
///********************************************************************************************************************/
/// @brief :运动进行中数据记录界面
///********************************************************************************************************************/
OHOS::UIViewGroup *SportingView::InitsportingDataRecordView(OHOS::UIViewGroup **sportingDataRecordView_,
SportTypeIndex index)
{
if (*sportingDataRecordView_ == nullptr) {
*sportingDataRecordView_ = new UIViewGroup();
}
(*sportingDataRecordView_)->SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION);
ImageInfo *imgInfo =
ImageCacheManager::GetInstance().LoadOneInMultiRes(g_pv_Sport[index].imgIconResId, SPORT_IMAGE_BIN_PATH);
UIDrawImageScale(&imgSportIcon_, 193, 40, imgInfo, 0.6, 0.6, 30, 30);
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_HR_01, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&imgHr01, 0, 225, imgInfo);
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_HR_02, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&imgHr02, 0, 29, imgInfo);
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_HR_03, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&imgHr03, 113, 0, imgInfo);
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_HR_04, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&imgHr04, 339, 30, imgInfo);
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_HR_05, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&imgHr05, 338, 225, imgInfo);
InitLabelHorCenter(sportingRtcLabel_, 72, 301, OHOS::HORIZONTAL_RESOLUTION, "00:00:00",
TJD_DIN_MEDIUM_FONT_FILENAME);
InitLabel(stepLabel_, 50, 170, 203, "00000", TJD_DIN_MEDIUM_FONT_FILENAME);
InitLabel(caloriesLabel_, 50, 333, 203, "0000", TJD_DIN_MEDIUM_FONT_FILENAME);
InitLabel(heartRateLabel_, 50, 197, 122, "---", TJD_DIN_MEDIUM_FONT_FILENAME);
InitLabel(distanceLabel_, 50, 45, 203, "0.00", TJD_DIN_MEDIUM_FONT_FILENAME);
// InitLabel(stepUnitLabel_, 30, 222, 258, "步");
stepUnitLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30);
stepUnitLabel_.SetTextId(STR_ID_547);
stepUnitLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT);
stepUnitLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
stepUnitLabel_.SetPosition(222, 258);
stepUnitLabel_.SetStyle(STYLE_TEXT_OPA, 0xff * 0.3);
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_SPORTING_KCAL, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&imgCaloriesIcon_, 126, 219, imgInfo);
// InitLabel(caloriesUnitLabel_, 30, 349, 258, "千卡");
caloriesUnitLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30);
caloriesUnitLabel_.SetTextId(STR_ID_576);
caloriesUnitLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT);
caloriesUnitLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
caloriesUnitLabel_.SetPosition(349, 258);
caloriesUnitLabel_.SetStyle(STYLE_TEXT_OPA, 0xff * 0.3);
// InitLabelHorCenter(sportingTimeLabel_, 30, 378, OHOS::HORIZONTAL_RESOLUTION, "时间");
sportingTimeLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30);
sportingTimeLabel_.SetTextId(STR_ID_594);
// sportingTimeLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT);
sportingTimeLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
sportingTimeLabel_.SetPosition(0, 378, 466, 42);
sportingTimeLabel_.SetStyle(STYLE_TEXT_OPA, 0xff * 0.3);
OHOS::UIImageView *imgHrIcon = new UIImageView();
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_HR, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&imgHrIcon_, 130, 143, imgInfo);
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_TRIANGLE, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&imgPoint_, 0, 0, imgInfo);
// imgPoint_.Rotate(10, VIEW_CENTER);
// imgPoint_.Invalidate();
// InitLabel(heartRateUnitLabel_, 30, , 140, "次/分");
heartRateUnitLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30);
heartRateUnitLabel_.SetTextId(STR_ID_110);
heartRateUnitLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT);
heartRateUnitLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
heartRateUnitLabel_.SetPosition(276, 140);
heartRateUnitLabel_.SetStyle(STYLE_TEXT_OPA, 0xff * 0.3);
// InitLabel(distanceUnitLabel_, 30, 57, 258, "千米");
distanceUnitLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30);
distanceUnitLabel_.SetTextId(STR_ID_632);
distanceUnitLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT);
distanceUnitLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
distanceUnitLabel_.SetPosition(57, 258);
distanceUnitLabel_.SetStyle(STYLE_TEXT_OPA, 0xff * 0.3);
sportingPage.SetPosition(205, 422);
sportingPage.Resize(16, 16);
sportingPage.SetStyle(STYLE_BACKGROUND_COLOR, 0xff262626);
sportingPage.SetStyle(STYLE_BORDER_RADIUS, 16);
lastPage.SetPosition(245, 422);
lastPage.Resize(16, 16);
lastPage.SetStyle(STYLE_BACKGROUND_COLOR, 0xffffffff);
lastPage.SetStyle(STYLE_BORDER_RADIUS, 16);
firstInterval.SetPosition(144, 199);
firstInterval.Resize(2, 98);
firstInterval.SetStyle(STYLE_BACKGROUND_COLOR, 0xFF646464);
secondInterval.SetPosition(316, 199);
secondInterval.Resize(2, 98);
secondInterval.SetStyle(STYLE_BACKGROUND_COLOR, 0xFF646464);
(*sportingDataRecordView_)->Add(&imgSportIcon_);
(*sportingDataRecordView_)->Add(&imgHr01);
(*sportingDataRecordView_)->Add(&imgHr02);
(*sportingDataRecordView_)->Add(&imgHr03);
(*sportingDataRecordView_)->Add(&imgHr04);
(*sportingDataRecordView_)->Add(&imgHr05);
(*sportingDataRecordView_)->Add(&imgHrIcon_);
(*sportingDataRecordView_)->Add(&imgPoint_);
(*sportingDataRecordView_)->Add(&sportingRtcLabel_);
(*sportingDataRecordView_)->Add(&stepLabel_);
(*sportingDataRecordView_)->Add(&stepUnitLabel_);
(*sportingDataRecordView_)->Add(&caloriesLabel_);
(*sportingDataRecordView_)->Add(&caloriesUnitLabel_);
(*sportingDataRecordView_)->Add(&heartRateLabel_);
(*sportingDataRecordView_)->Add(&heartRateUnitLabel_);
(*sportingDataRecordView_)->Add(&distanceLabel_);
(*sportingDataRecordView_)->Add(&distanceUnitLabel_);
(*sportingDataRecordView_)->Add(&sportingPage);
(*sportingDataRecordView_)->Add(&lastPage);
(*sportingDataRecordView_)->Add(&firstInterval);
(*sportingDataRecordView_)->Add(&secondInterval);
(*sportingDataRecordView_)->Add(&sportingTimeLabel_);
(*sportingDataRecordView_)->Add(&imgCaloriesIcon_);
return (*sportingDataRecordView_);
}
void SportingView::SportingViewRefresh()
{
static_print_info("lines = %d ,func = %s\n", __LINE__, __FUNCTION__);
auto iconIndex = TjdUiAppSportView::GetInstance()->currentIconIndex_;
// TjdUiAppSportPresenter::GetInstance()->SetCurrentSportingData();
switch (iconIndex) {
case SPORT_TYPE_01_OUTDOOR_RUNNING_INDEX:
case SPORT_TYPE_02_OUTDOOR_WALKING_INDEX:
case SPORT_TYPE_04_FOOTBALL_INDEX:
case SPORT_TYPE_05_BASKETBALL_INDEX:
case SPORT_TYPE_12_ON_FOOT_INDEX:
case SPORT_TYPE_13_STAIRCASE_INDEX:
stepLabel_.SetPosition(170, 203);
stepLabel_.SetVisible(true);
stepUnitLabel_.SetPosition(222, 258);
stepUnitLabel_.SetVisible(true);
caloriesLabel_.SetPosition(333, 203);
caloriesUnitLabel_.SetPosition(349, 258);
distanceLabel_.SetPosition(45, 203);
distanceLabel_.SetVisible(true);
distanceUnitLabel_.SetPosition(57, 258);
distanceUnitLabel_.SetVisible(true);
firstInterval.SetVisible(true);
secondInterval.SetVisible(true);
firstInterval.SetPosition(144, 199);
secondInterval.SetPosition(316, 199);
imgCaloriesIcon_.SetVisible(false);
break;
case SPORT_TYPE_09_INDOOR_SWIMMI_INDEX:
case SPORT_TYPE_10_OUTDOOR_SWIMM_INDEX:
case SPORT_TYPE_11_CYCLING_INDEX:
case SPORT_TYPE_51_RIDING_INDEX ... SPORT_TYPE_57_MOTORBOAT_INDEX:
stepLabel_.SetVisible(false);
stepUnitLabel_.SetVisible(false);
caloriesLabel_.SetPosition(278, 203);
caloriesUnitLabel_.SetPosition(299, 258);
distanceLabel_.SetPosition(101, 203);
distanceLabel_.SetVisible(true);
distanceUnitLabel_.SetPosition(115, 258);
distanceUnitLabel_.SetVisible(true);
firstInterval.SetVisible(true);
firstInterval.SetPosition(232, 199);
secondInterval.SetVisible(false);
imgCaloriesIcon_.SetVisible(false);
break;
default:
stepLabel_.SetVisible(false);
stepUnitLabel_.SetVisible(false);
caloriesLabel_.SetPosition(197, 212);
caloriesUnitLabel_.SetPosition(314, 230);
distanceLabel_.SetVisible(false);
distanceUnitLabel_.SetVisible(false);
firstInterval.SetVisible(false);
secondInterval.SetVisible(false);
imgCaloriesIcon_.SetVisible(true);
break;
}
if (returnToDial) {
SportingData_t curSportingData = TjdUiAppSportModel::GetInstance()->GetServiceSportData(); // 读取数据
char recoverDate[10] = {0};
uint32_t hours = curSportingData.exerciseDuration / 3600;
uint32_t minutes = (curSportingData.exerciseDuration % 3600) / 60;
uint32_t seconds = curSportingData.exerciseDuration % 60;
sprintf(recoverDate, "%02d:%02d:%02d", hours, minutes, seconds);
sportingRtcLabel_.SetText(recoverDate);
memset(recoverDate, 0, sizeof(recoverDate));
sprintf(recoverDate, "%05d", curSportingData.steps);
stepLabel_.SetText(recoverDate);
memset(recoverDate, 0, sizeof(recoverDate));
sprintf(recoverDate, "%04d", curSportingData.calories);
caloriesLabel_.SetText(recoverDate);
memset(recoverDate, 0, sizeof(recoverDate));
if (curSportingData.heartRate)
sprintf(recoverDate, "%d", curSportingData.heartRate);
else
sprintf(recoverDate, "---");
heartRateLabel_.SetText(recoverDate);
memset(recoverDate, 0, sizeof(recoverDate));
sprintf(recoverDate, "%.2f", curSportingData.distance / 1000.0f);
distanceLabel_.SetText(recoverDate);
} else {
sportingRtcLabel_.SetText("00:00:00");
stepLabel_.SetText("00000");
caloriesLabel_.SetText("0000");
distanceLabel_.SetText("0.00");
heartRateLabel_.SetText("---");
}
ImageInfo *imgInfo =
ImageCacheManager::GetInstance().LoadOneInMultiRes(g_pv_Sport[iconIndex].imgIconResId, SPORT_IMAGE_BIN_PATH);
imgSportIcon_.SetSrc(imgInfo);
imgSportIcon_.Invalidate();
}
///********************************************************************************************************************/
/// @brief :运动进行中暂停或继续界面
///********************************************************************************************************************/
void StopAnimatorCallback::Callback(OHOS::UIView *view)
{
if (animator_ == nullptr || canvas_ == nullptr) {
return;
}
canvas_->Clear();
OHOS::Point center = {233, 233};
OHOS::ColorType color;
color.full = 0xFF660e16;
paint_.SetStrokeColor(color);
canvas_->DrawArc(center, 223, 360, 0, paint_);
color.full = 0xFFFE2337;
paint_.SetStrokeColor(color);
int16_t value = OHOS::EasingEquation::LinearEaseNone(0, 359, animator_->GetRunTime(), animator_->GetTime());
canvas_->DrawArc(center, 223, 360, value, paint_);
if (animator_->GetRunTime() >= animator_->GetTime()) {
animator_->Stop();
auto sportView = TjdUiAppSportView::GetInstance();
auto sportingView = SportingView::GetInstance();
Time currentTime = sportView->GetCurrentTime(sportingView->GetSportingRtcLabelText());
sportingView->SetSwipeViewDraggable(true);
sportingView->ResetSwipeView();
// sportingView->SetSportingRtcLabelText("00:00:00");
sportingView->SetPauseOrContinueCheckBoxState(1);
switch (SportingView::sportType) {
case SPORT_TYPE_1:
printf("SportType = %d, Step = %d\n", SportingView::sportType, SportingView::GetInstance()->GetStep());
if (SportingView::GetInstance()->GetStep() < 100) { // 1分钟后开始记录数据(临时调试)
sportView->ShowTargetView(SPORT_END_NODATA_VIEW);
} else {
sportView->ShowTargetView(SPORT_END_DATA_VIEW);
}
break;
case SPORT_TYPE_2:
case SPORT_TYPE_3:
if (currentTime.minutes < 1) { // 1分钟后开始记录数据(临时调试)
sportView->ShowTargetView(SPORT_END_NODATA_VIEW);
} else {
sportView->ShowTargetView(SPORT_END_DATA_VIEW);
}
break;
}
}
}
void StopAnimatorCallback::OnStop(OHOS::UIView &view) { canvas_->Clear(); }
std::vector<Coordinate> NewTrajectory = {
{22.578361511230469f, 113.90731811523438f}, {22.578344345092773f, 113.90730285644531f},
{22.578323364257812f, 113.90728759765625f}, {22.578306198120117f, 113.90727233886719f},
{22.578290939331055f, 113.90725708007812f}, {22.57826042175293f, 113.90724182128906f},
{22.5782299041748f, 113.9072265625f}, {22.578201293945312f, 113.90721130371094f},
{22.578180313110352f, 113.9072265625f}, {22.578153610229492f, 113.90725708007812f},
{22.578121185302734f, 113.90727996826172f}, {22.578102111816406f, 113.90729522705078f},
{22.57807731628418f, 113.90732574462891f}, {22.578042984008789f, 113.90735626220703f},
{22.578006744384766f, 113.90739440917969f}, {22.577968597412109f, 113.90742492675781f},
{22.577959060668945f, 113.90745544433594f}, {22.578006744384766f, 113.90748596191406f},
{22.578046798706055f, 113.90750885009766f}, {22.578084945678711f, 113.90747833251953f},
{22.5781192779541f, 113.90743255615234f}, {22.578145980834961f, 113.90738677978516f},
{22.57819938659668f, 113.90732574462891f}, {22.578237533569336f, 113.90727996826172f},
{22.578277587890625f, 113.90724182128906f}, {22.578315734863281f, 113.90721893310547f},
{22.57832145690918f, 113.9072265625f}, {22.578342437744141f, 113.90726470947266f},
{22.578371047973633f, 113.90730285644531f}, {22.578403472900391f, 113.90734100341797f},
{22.578405380249023f, 113.90737915039062f}, {22.578407287597656f, 113.90738677978516f}};
static void gpsTrackTimerCallBack(void *arg)
{
GraphicService::GetInstance()->PostGraphicEvent(std::bind(
[](void *arg) {
OHOS::UICanvas *canvas_ = static_cast<OHOS::UICanvas *>(arg);
if (canvas_ == nullptr)
return;
auto sportingView = SportingView::GetInstance();
if (sportingView == nullptr)
return;
std::vector<Coordinate> &trajectory = sportingView->GetTrajectory();
sportingView->UpdateGPSTrack(canvas_, trajectory);
if (gpsTrack < NewTrajectory.size() - 1)
gpsTrack++;
},
arg));
}
void SportingView::GPSCanvasAutoCenter()
{
gpsCanvas_.SetPosition((466 - GPS_CAVAS_WIDTH) / 2, (466 - GPS_CAVAS_HEIGHT) / 2, GPS_CAVAS_WIDTH,
GPS_CAVAS_HEIGHT);
UpdateGPSTrack(&gpsCanvas_, trajectory);
Invalidate();
}
void SportingView::UpdateGPSTrack(OHOS::UICanvas *canvas, std::vector<Coordinate> &trajectory)
{
canvas->Clear();
Paint paint;
paint.SetStrokeColor(Color::Green());
paint.SetStrokeWidth(2);
paint.SetOpacity(OPA_OPAQUE);
gnss_data_t gps_data = TjdUiAppSportModel::GetInstance()->GPSGetData();
Coordinate centerPoint;
centerPoint.latitude = gps_data.latitude;
centerPoint.longitude = gps_data.longitude;
// centerPoint = NewTrajectory[gpsTrack];
trajectory.push_back(centerPoint);
// 计算动态比例尺(根据最大偏移量自动缩放)
double maxLatOffset = 0;
double maxLonOffset = 0;
for (const auto &coord : trajectory) {
// printf("(coord.latitude%.15f,coord.longitude %.15f)\n", coord.latitude, coord.longitude);
double latOffset = std::abs(coord.latitude - centerPoint.latitude);
double lonOffset = std::abs(coord.longitude - centerPoint.longitude);
if (latOffset > maxLatOffset)
maxLatOffset = latOffset;
if (lonOffset > maxLonOffset)
maxLonOffset = lonOffset;
}
// printf("line = %d================\n", __LINE__);
// 防止除零
const double epsilon = 1e-9;
maxLatOffset = std::max(maxLatOffset, epsilon);
maxLonOffset = std::max(maxLonOffset, epsilon);
// 计算每度对应的像素数取安全比例的80%
const double latScale = (GPS_CAVAS_HEIGHT / 2.0 * 0.8) / maxLatOffset;
const double lonScale = (GPS_CAVAS_WIDTH / 2.0 * 0.8) / maxLonOffset;
const double scale = std::min(latScale, lonScale);
// printf("line = %d================\n", __LINE__);
bool isFirst = true;
Point prevPosition;
for (const auto &point : trajectory) {
// 计算相对中心点的偏移量
double latOffset = point.latitude - centerPoint.latitude;
double lonOffset = point.longitude - centerPoint.longitude;
// 转换为屏幕坐标(中心点为屏幕中心)
int x = static_cast<int>(GPS_CAVAS_WIDTH / 2 + lonOffset * scale);
int y = static_cast<int>(GPS_CAVAS_HEIGHT / 2 - latOffset * scale); // Y轴翻转
// 边界保护
x = std::max(0, std::min(x, GPS_CAVAS_WIDTH - 1));
y = std::max(0, std::min(y, GPS_CAVAS_HEIGHT - 1));
Point position{x, y};
// static_print_info("Screen: (%d, %d)\n", position.x, position.y);
if (isFirst) {
Paint centerPaint;
centerPaint.SetStrokeColor(Color::Green());
centerPaint.SetStrokeWidth(4);
canvas->DrawCircle(position, 2, centerPaint); // 中心点画红色圆点
canvas->SetStartPosition(position);
isFirst = false;
} else {
canvas->DrawLine(position, paint);
prevPosition = position;
}
}
}
OHOS::UIViewGroup *SportingView::InitSportingGPSView(OHOS::UIViewGroup **sportingGPSView_)
{
static_print_info("TjdUiAppSportView::InitSportingGPSViewInit...");
if (*sportingGPSView_ == nullptr) {
*sportingGPSView_ = new UIViewGroup();
}
(*sportingGPSView_)->SetViewId("sportingGPSView");
(*sportingGPSView_)->SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION);
(*sportingGPSView_)->SetViewIndex(0);
ImageInfo *imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_SHRINK, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&imgShrink_, 22, 194, imgInfo);
imgShrink_.SetTouchable(true);
imgShrink_.SetViewId("imgShrink");
imgShrink_.SetOnClickListener(&GPSTrackListener_);
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_ENLARGE, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&imgEnlarge_, 376, 194, imgInfo);
imgEnlarge_.SetTouchable(true);
imgEnlarge_.SetViewId("imgEnlarge_");
imgEnlarge_.SetOnClickListener(&GPSTrackListener_);
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_BJ_GPS, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&imgState_, 77, 378, imgInfo);
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_DESTINATION, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&imgDestination_, 222, 218, imgInfo);
gpsCanvas_.SetPosition(126, 107, GPS_CAVAS_WIDTH, GPS_CAVAS_HEIGHT);
// trackAnimator_->Start();
lbState_.SetFont(TJD_VECTOR_FONT_FILENAME, 30);
lbState_.SetTextId(STR_ID_194);
lbState_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
lbState_.SetPosition(0, 400, 466, 47);
if (gpsTrackTimer_ == nullptr) {
gpsTrackTimer_ = new OHOS::GraphicTimer(1000, gpsTrackTimerCallBack, (void *)&gpsCanvas_, true);
}
(*sportingGPSView_)->Add(&gpsCanvas_);
(*sportingGPSView_)->Add(&imgShrink_);
(*sportingGPSView_)->Add(&imgEnlarge_);
(*sportingGPSView_)->Add(&imgState_);
(*sportingGPSView_)->Add(&imgDestination_);
(*sportingGPSView_)->Add(&lbState_);
return (*sportingGPSView_);
}
OHOS::UIViewGroup *SportingView::InitSportingPauseOrContinueView(OHOS::UIViewGroup **sportingPauseOrContinueView_)
{
static_print_info("TjdUiAppSportView::PauseOrContinueDuringSportingViewInit...");
if (*sportingPauseOrContinueView_ == nullptr) {
*sportingPauseOrContinueView_ = new UIViewGroup();
}
(*sportingPauseOrContinueView_)->SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION);
(*sportingPauseOrContinueView_)->SetViewIndex(0);
ImageInfo *imgInfo =
ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_RELEASE, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&imgEnd_, 54, 168, imgInfo);
imgEnd_.SetTouchable(true);
if (imgEndOnTouchListener_ == nullptr)
imgEndOnTouchListener_ = new ImgEndOnTouchListener();
imgEnd_.SetOnTouchListener(imgEndOnTouchListener_);
auto selectedImg = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_KEEP, SPORT_IMAGE_BIN_PATH);
auto unselectedImg = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_PAUSE, SPORT_IMAGE_BIN_PATH);
pauseOrContinueCheckBox_.SetPosition(282, 168, 130, 130);
pauseOrContinueCheckBox_.SetState(UICheckBox::UNSELECTED);
pauseOrContinueCheckBox_.SetImages(selectedImg, unselectedImg);
pauseOrContinueCheckBox_.SetViewId("pauseOrContinueCheckBox_");
if (sportViewOnClickedListener_ == nullptr)
sportViewOnClickedListener_ = new SportViewOnClickedListener();
pauseOrContinueCheckBox_.SetOnClickListener(sportViewOnClickedListener_);
canvas_.SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION);
stopAnimatorCallback_ = new StopAnimatorCallback(&canvas_);
animator_ = new OHOS::Animator(stopAnimatorCallback_, nullptr, 3000, true);
stopAnimatorCallback_->SetAnimator(animator_);
prePage.SetPosition(245, 422);
prePage.Resize(16, 16);
prePage.SetStyle(STYLE_BACKGROUND_COLOR, 0xff262626);
prePage.SetStyle(STYLE_BORDER_RADIUS, 16);
PauseOrContinuePage.SetPosition(205, 422);
PauseOrContinuePage.Resize(16, 16);
PauseOrContinuePage.SetStyle(STYLE_BACKGROUND_COLOR, 0xffffffff);
PauseOrContinuePage.SetStyle(STYLE_BORDER_RADIUS, 16);
// Add to rootView
(*sportingPauseOrContinueView_)->Add(&canvas_);
(*sportingPauseOrContinueView_)->Add(&imgEnd_); // <20><><EFBFBD><EFBFBD>û<EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>
(*sportingPauseOrContinueView_)->Add(&pauseOrContinueCheckBox_);
(*sportingPauseOrContinueView_)->Add(&prePage);
(*sportingPauseOrContinueView_)->Add(&PauseOrContinuePage);
return (*sportingPauseOrContinueView_);
}
void SportingView::SetSportingRtcLabelText(Time currentTime)
{
char timeStr[20] = {0};
sprintf(timeStr, "%02d:%02d:%02d", currentTime.hours, currentTime.minutes, currentTime.seconds);
sportingRtcLabel_.SetText(timeStr);
sportingRtcLabel_.Invalidate();
}
uint32_t SportingView::GetStep() { return std::stoi(std::string(stepLabel_.GetText())); }
#pragma endregion
#pragma region 运动结束无数据界面
EndOfSportNoDataView::EndOfSportNoDataView()
{
static_print_info("EndOfSportNoDataView::EndOfSportNoDataView");
SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION);
SetDraggable(true);
SetOnDragListener(TjdUiAppSportPresenter::GetInstance());
// InitLabel(remindLabel_, 34, 54, 179, "运动数据不足,\n本次锻炼数据将不保存");
remindLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 34);
remindLabel_.SetTextId(STR_ID_197);
remindLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
remindLabel_.SetPosition(0, 179, 466, 47);
remindLabelTip_.SetFont(TJD_VECTOR_FONT_FILENAME, 34);
remindLabelTip_.SetTextId(STR_ID_198);
remindLabelTip_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_WRAP);
remindLabelTip_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
remindLabelTip_.SetPosition(60, 226, 346, 47);
ImageInfo *imgInfo =
ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_CONFIRM, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&imgConfirm_, 187, 352, imgInfo);
imgConfirm_.SetTouchable(true);
imgConfirm_.SetViewId("NoDataConfirm_");
imgConfirm_.SetOnClickListener(&noDataViewOnClickedListener_);
Add(&remindLabel_);
Add(&remindLabelTip_);
Add(&imgConfirm_);
}
void EndOfSportNoDataView::ShowView()
{
TjdUiAppSportModel::GetInstance()->RemoveFile(str);
SetVisible(true);
}
EndOfSportNoDataView::~EndOfSportNoDataView()
{
static_print_info("EndOfSportNoDataView Destory=======\n");
RemoveAll();
}
#pragma endregion
#pragma region 运动结束数据界面
EndOfSportDataView::EndOfSportDataView()
{
static_print_info("TjdUiAppSportView::NormalEndingViewInit...");
g_EndOfSportDataView = this;
SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION);
SetStyle(STYLE_BACKGROUND_OPA, 0);
SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION);
SetStyle(STYLE_BACKGROUND_OPA, 0);
SetScrollBlankSize(20);
SetHorizontalScrollState(false);
SetThrowDrag(true); // 设置结束拖动时,是否产生惯性滑动动效
SetElastic(true);
SetDraggable(true);
SetOnDragListener(TjdUiAppSportPresenter::GetInstance());
GPSMap_.SetPosition(126, 156, 214, 252);
GPSMap_.SetTouchable(false);
DataView_.SetPosition(0, 493, 466, 100);
// InitLabel(dataViewTitlie_, 28, 176, 16, "运动结束");
dataViewTitlie_.SetFont(TJD_VECTOR_FONT_FILENAME, 28);
dataViewTitlie_.SetTextId(STR_ID_199);
dataViewTitlie_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_MARQUEE);
dataViewTitlie_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
dataViewTitlie_.SetPosition(167, 17, 132, 40);
ImageInfo *imgInfo =
ImageCacheManager::GetInstance().LoadOneInMultiRes(g_pv_Sport[0].imgIconResId, SPORT_IMAGE_BIN_PATH);
UIDrawImageScale(&SportIcon_, 203, 60, imgInfo, 0.6, 0.6, 30, 30);
InitView();
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_CONFIRM, SPORT_IMAGE_BIN_PATH);
imgConfirm_.SetPosition(187, 333); // widget's left position and top position
imgConfirm_.SetSrc(imgInfo);
imgConfirm_.SetTouchable(true);
imgConfirm_.SetViewId("DataConfirm_");
imgConfirm_.SetOnClickListener(&dataViewOnClickedListener_);
Add(&dataViewTitlie_);
Add(&SportIcon_);
Add(&GPSMap_);
Add(&DataView_);
Add(&imgConfirm_);
}
void EndOfSportDataView::InitView(void)
{
static_print_info("InitView...");
canvas_.SetPosition(0, 0, 214, 252);
canvas_.Resize(OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION);
canvas_.SetStyle(OHOS::STYLE_BACKGROUND_COLOR, 0xFF000000);
canvas_.SetTouchable(false);
ImageInfo *imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_TIME, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&sportTimeIcon_, 60, 21, imgInfo);
// InitLabel(sportTimeLabel_, 30, 126, 0, "运动时间");
sportTimeLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30);
sportTimeLabel_.SetTextId(STR_ID_200);
sportTimeLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT);
sportTimeLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
sportTimeLabel_.SetPosition(126, 0, 124, 42);
sportTimeLabel_.SetTextColor(Color::GetColorFromRGBA(0x6B, 0x6B, 0x6B, 0xff));
InitLabel(curSportTime_, 60, 125, 39, "00:00:00", TJD_DIN_MEDIUM_FONT_FILENAME);
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_HR, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&heartRateIcon_, 59, 166, imgInfo);
// InitLabel(averageHeartRateLabel_, 30, 126, 139, "平均心率");
averageHeartRateLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30);
averageHeartRateLabel_.SetTextId(STR_ID_111);
averageHeartRateLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT);
averageHeartRateLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
averageHeartRateLabel_.SetPosition(126, 139, 124, 42);
averageHeartRateLabel_.SetTextColor(Color::GetColorFromRGBA(0x6B, 0x6B, 0x6B, 0xff));
InitLabel(curAverageHeartRate_, 60, 130, 178, "---", TJD_DIN_MEDIUM_FONT_FILENAME);
InitLabel(curAverageHeartRateUnitLabel_, 30, 230, 194, "Bpm");
curAverageHeartRateUnitLabel_.SetTextColor(Color::GetColorFromRGBA(0x6B, 0x6B, 0x6B, 0xff));
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_KCAL, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&calorieIcon_, 59, 295, imgInfo);
// InitLabel(calorieLabel_, 30, 126, 284, "卡路里");
calorieLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30);
calorieLabel_.SetTextId(STR_ID_201);
calorieLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT);
calorieLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
calorieLabel_.SetPosition(126, 284, 94, 42);
calorieLabel_.SetTextColor(Color::GetColorFromRGBA(0x6B, 0x6B, 0x6B, 0xff));
InitLabel(curCalorie_, 60, 125, 317, "0000", TJD_DIN_MEDIUM_FONT_FILENAME);
InitLabel(curCalorieUnitLabel_, 30, 263, 333, "Kcal");
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_SPEED, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&speedIcon_, 62, 578, imgInfo);
// InitLabel(speed_, 30, 126, 557, "配速");
speed_.SetFont(TJD_VECTOR_FONT_FILENAME, 30);
speed_.SetTextId(STR_ID_203);
speed_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT);
speed_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
speed_.SetPosition(126, 557, 64, 42);
speed_.SetTextColor(Color::GetColorFromRGBA(0x6B, 0x6B, 0x6B, 0xff));
InitLabel(curSpeed_, 60, 126, 591, "00'00'", TJD_DIN_MEDIUM_FONT_FILENAME);
InitLabel(curSpeedUnitLabel_, 30, 164, 612, "min/km");
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_DISTANCE, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&sportDistanceIcon_, 60, 435, imgInfo);
// InitLabel(sportDistanceLabel_, 30, 126, 418, "公里数");
sportDistanceLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30);
sportDistanceLabel_.SetTextId(STR_ID_202);
sportDistanceLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT);
sportDistanceLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
sportDistanceLabel_.SetPosition(126, 418, 94, 42);
sportDistanceLabel_.SetTextColor(Color::GetColorFromRGBA(0x6B, 0x6B, 0x6B, 0xff));
InitLabel(curSportDistance_, 60, 125, 457, "0.00", TJD_DIN_MEDIUM_FONT_FILENAME);
InitLabel(curSportDistanceUnitLabel_, 30, 295, 473, "Km");
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_STEP, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&stepIcon_, 60, 714, imgInfo);
// InitLabel(curStepLabel_, 30, 126, 695, "步数");
curStepLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30);
curStepLabel_.SetTextId(STR_ID_204);
curStepLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT);
curStepLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
curStepLabel_.SetPosition(126, 695, 64, 42);
curStepLabel_.SetTextColor(Color::GetColorFromRGBA(0x6B, 0x6B, 0x6B, 0xff));
InitLabel(curStep_, 60, 125, 735, "00000", TJD_DIN_MEDIUM_FONT_FILENAME);
InitLabel(curStepUnitLabel_, 30, 295, 751, "Steps");
imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_FREQUENCY, SPORT_IMAGE_BIN_PATH);
UiDrawImage(&stepFrequencyIcon_, 62, 859, imgInfo);
// InitLabel(stepFrequencyLabel_, 30, 126, 834, "步幅");
stepFrequencyLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30);
stepFrequencyLabel_.SetTextId(STR_ID_205);
stepFrequencyLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT);
stepFrequencyLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER);
stepFrequencyLabel_.SetPosition(126, 834, 64, 42);
stepFrequencyLabel_.SetTextColor(Color::GetColorFromRGBA(0x6B, 0x6B, 0x6B, 0xff));
InitLabel(curStepFrequency_, 60, 125, 869, "0.0", TJD_DIN_MEDIUM_FONT_FILENAME);
InitLabel(curStepFrequencyUnitLabel_, 30, 295, 890, "M");
TjdUiUtils::AdjustViewOffset(curAverageHeartRateUnitLabel_, curAverageHeartRate_, 11,
TjdUiUtils::OffsetDirection::OFFSET_RIGHT);
TjdUiUtils::AdjustViewOffset(curCalorieUnitLabel_, curCalorie_, 15, TjdUiUtils::OffsetDirection::OFFSET_RIGHT);
TjdUiUtils::AdjustViewOffset(curSpeedUnitLabel_, curSpeed_, 11, TjdUiUtils::OffsetDirection::OFFSET_RIGHT);
TjdUiUtils::AdjustViewOffset(curSportDistanceUnitLabel_, curSportDistance_, 11,
TjdUiUtils::OffsetDirection::OFFSET_RIGHT);
TjdUiUtils::AdjustViewOffset(curStepUnitLabel_, curStep_, 11, TjdUiUtils::OffsetDirection::OFFSET_RIGHT);
TjdUiUtils::AdjustViewOffset(curStepFrequencyUnitLabel_, curStepFrequency_, 11,
TjdUiUtils::OffsetDirection::OFFSET_RIGHT);
GPSMap_.Add(&canvas_);
}
void EndOfSportDataView::ChangeSportType(SportType type)
{
DataView_.RemoveAll();
DataView_.Add(&sportTimeIcon_);
DataView_.Add(&sportTimeLabel_);
DataView_.Add(&curSportTime_);
DataView_.Add(&heartRateIcon_);
DataView_.Add(&averageHeartRateLabel_);
DataView_.Add(&curAverageHeartRateUnitLabel_);
DataView_.Add(&curAverageHeartRate_);
DataView_.Add(&calorieIcon_);
DataView_.Add(&calorieLabel_);
DataView_.Add(&curCalorieUnitLabel_);
DataView_.Add(&curCalorie_);
switch (SportingView::sportType) {
case SPORT_TYPE_1:
DataView_.Add(&sportDistanceIcon_);
DataView_.Add(&sportDistanceLabel_);
DataView_.Add(&curSportDistanceUnitLabel_);
DataView_.Add(&curSportDistance_);
DataView_.Add(&speedIcon_);
DataView_.Add(&speed_);
DataView_.Add(&curSpeedUnitLabel_);
DataView_.Add(&curSpeed_);
DataView_.Add(&stepIcon_);
DataView_.Add(&curStep_);
DataView_.Add(&curStepUnitLabel_);
DataView_.Add(&curStepLabel_);
DataView_.Add(&stepFrequencyLabel_);
DataView_.Add(&curStepFrequencyUnitLabel_);
DataView_.Add(&stepFrequencyIcon_);
DataView_.Add(&curStepFrequency_);
break;
case SPORT_TYPE_2:
DataView_.Add(&sportDistanceIcon_);
DataView_.Add(&sportDistanceLabel_);
DataView_.Add(&curSportDistanceUnitLabel_);
DataView_.Add(&curSportDistance_);
break;
default:
break;
}
auto height = DataView_.GetChildrenTail()->GetY() + DataView_.GetChildrenTail()->GetHeight();
DataView_.Resize(466, height);
imgConfirm_.SetY(DataView_.GetY() + height + 54);
}
#define READ_DATA_FROM_FILE 0
void EndOfSportDataView::EndOfSportDataViewRefresh(std::string fileName)
{
static_print_info("EndOfSportDataView::EndOfSportDataViewRefresh\n");
char temp[20] = {0};
auto sportModel = TjdUiAppSportModel::GetInstance();
cJSON *json = sportModel->ReadAndParseJson(fileName.c_str());
#if 1 // 临时调试
std::vector<Coordinate> trajectory = sportModel->TrackAnalysis(json);
#else
std::vector<Coordinate> trajectory = {
{22.580576, 113.917157}, {22.580627, 113.917229}, {22.580627, 113.917229},
{22.580765, 113.917386}, {22.58084, 113.917481}, {22.58094, 113.917589},
};
#endif
DrawSportTrack(trajectory);
// 释放 JSON 对象
cJSON_Delete(json);
// static_print_info("===%s===\n", SportingView::GetInstance()->sportingRtcLabel_.GetText());
#if READ_DATA_FROM_FILE
Time time = TjdUiAppSportView::GetInstance()->GetCurrentTime(sportModel->KeyValueAnalysis(json, "运动时间"));
#else
Time time =
TjdUiAppSportView::GetInstance()->GetCurrentTime(SportingView::GetInstance()->sportingRtcLabel_.GetText());
// Time time = TjdUiAppSportView::GetInstance()->GetCurrentTime(sportModel->KeyValueAnalysis(json, "SportTime"));
#endif
int16_t tempDistance = 0;
uint32_t totalTime = time.hours * 3600 + time.minutes * 60 + time.seconds;
double distance = std::stof(std::string(SportingView::GetInstance()->distanceLabel_.GetText()));
uint32_t step = std::stoi(std::string(SportingView::GetInstance()->stepLabel_.GetText()));
auto iconIndex = TjdUiAppSportView::GetInstance()->currentIconIndex_;
ImageInfo *imgInfo =
ImageCacheManager::GetInstance().LoadOneInMultiRes(g_pv_Sport[iconIndex].imgIconResId, SPORT_IMAGE_BIN_PATH);
if (imgInfo)
SportIcon_.SetSrc(imgInfo);
switch (SportingView::sportType) {
case SPORT_TYPE_1:
#if READ_DATA_FROM_FILE
curSportDistance_.SetText(sportModel->KeyValueAnalysis(json, "公里数"));
#else
curSportDistance_.SetText(SportingView::GetInstance()->distanceLabel_.GetText());
#endif
if (distance != 0) {
float pace = totalTime / distance / 60.0;
int minutes = static_cast<int>(pace);
int seconds = static_cast<int>((pace - minutes) * 60);
// 创建带单引号的目标字符串
stringstream finalStr;
finalStr << minutes << "'" << setw(2) << setfill('0') << seconds << "\"";
curSpeed_.SetText(finalStr.str().c_str());
printf("pace = %f, minutes = %d, seconds = %d\n", pace, minutes, seconds);
// memset(temp, 0, sizeof(temp));
// sprintf(temp, "%02d'%02d\"", totalTime / distance, totalTime % distance);
// curSpeed_.SetText(temp);
// curSpeed_.SetText("00'00\"");
} else {
curSpeed_.SetText("00'00\"");
}
#if READ_DATA_FROM_FILE
curStep_.SetText(sportModel->KeyValueAnalysis(json, "步数"));
#else
curStep_.SetText(SportingView::GetInstance()->stepLabel_.GetText());
#endif
if (step) {
memset(temp, 0, sizeof(temp));
tempDistance = (uint16_t)distance * 1000;
sprintf(temp, "%d.%01d\"", tempDistance / step, tempDistance % step);
curStepFrequency_.SetText(temp);
// curStepFrequency_.SetText("0.0"); // 先用假数据
} else
curStepFrequency_.SetText("0.0"); // 步频需要换算
break;
case SPORT_TYPE_2:
curSportDistance_.SetText(SportingView::GetInstance()->distanceLabel_.GetText());
break;
case SPORT_TYPE_3:
break;
default:
break;
}
#if READ_DATA_FROM_FILE
curSportTime_.SetText(sportModel->KeyValueAnalysis(json, "运动时间"));
curAverageHeartRate_.SetText(sportModel->KeyValueAnalysis(json, "平均心率"));
curCalorie_.SetText(sportModel->KeyValueAnalysis(json, "卡路里"));
#else
printf("SportTime = %s\n", SportingView::GetInstance()->sportingRtcLabel_.GetText());
curSportTime_.SetText(SportingView::GetInstance()->sportingRtcLabel_.GetText());
curAverageHeartRate_.SetText(SportingView::GetInstance()->heartRateLabel_.GetText());
curCalorie_.SetText(SportingView::GetInstance()->caloriesLabel_.GetText());
#endif
}
OHOS::Point EndOfSportDataView::latLonToScreen(const Coordinate &coordinate, double minLat, double maxLat,
double minLon, double maxLon, int screenWidth, int screenHeight)
{
Point point;
point.x = (coordinate.longitude - minLon) / (maxLon - minLon) * screenWidth;
point.y = screenHeight - (coordinate.latitude - minLat) / (maxLat - minLat) * screenHeight; // y轴翻转
return point;
}
void EndOfSportDataView::DrawSportTrack(std::vector<Coordinate> trajectory)
{
canvas_.Clear();
Paint paint;
// paint.SetStyle(Paint::PaintStyle::FILL_STYLE);
paint.SetStrokeColor(Color::Green());
paint.SetStrokeWidth(3);
paint.SetOpacity(OPA_OPAQUE);
// 获取最小和最大纬度和经度
double minLatitude = std::numeric_limits<double>::max();
double maxLatitude = std::numeric_limits<double>::lowest();
double minLongitude = std::numeric_limits<double>::max();
double maxLongitude = std::numeric_limits<double>::lowest();
for (const auto &coord : trajectory) {
if (coord.latitude < minLatitude)
minLatitude = coord.latitude;
if (coord.latitude > maxLatitude)
maxLatitude = coord.latitude;
if (coord.longitude < minLongitude)
minLongitude = coord.longitude;
if (coord.longitude > maxLongitude)
maxLongitude = coord.longitude;
}
const int screenWidth = 214;
const int screenHeight = 252;
bool isFirst = true; // 用于跟踪是否是第一个点
// 转换并输出屏幕坐标
for (const auto &point : trajectory) {
auto position =
latLonToScreen(point, minLatitude, maxLatitude, minLongitude, maxLongitude, screenWidth, screenHeight);
static_print_info("Screen: (%d, %d)\n", position.x, position.y);
if (isFirst) {
canvas_.BeginPath();
// canvas_.SetStartPosition(position);
canvas_.MoveTo(position);
isFirst = false; // 更新状态为不是第一个点
} else {
// canvas_.DrawLine(position, paint);
canvas_.LineTo(position);
}
}
canvas_.DrawPath(paint);
}
void EndOfSportDataView::ShowView()
{
static_print_info("====str=%s=====\n", str);
TjdUiUtils::ScrollByTop(*this);
// std::string new_fileName = TjdUiAppSportModel::GetInstance()->RenameSportDataFile(str);
printf("state = %d\n", TjdUiAppSportView::GetInstance()->GetGPState());
if (TjdUiAppSportView::GetInstance()->GetGPState()) {
DataView_.SetY(493);
GPSMap_.SetVisible(true);
} else {
DataView_.SetY(193);
GPSMap_.SetVisible(false);
}
ChangeSportType(SportingView::sportType);
EndOfSportDataViewRefresh(str);
SetVisible(true);
tjd_service_send_sport_end_record_data(str);
}
EndOfSportDataView *EndOfSportDataView::GetInstance() { return g_EndOfSportDataView; }
EndOfSportDataView::~EndOfSportDataView()
{
static_print_info("EndOfSportDataView Destory=======\n");
g_EndOfSportDataView = nullptr;
RemoveAll();
GPSMap_.RemoveAll();
DataView_.RemoveAll();
}
#pragma endregion
#pragma region 编辑运动
EditSportView::EditSportView()
{
g_pv_EditSportView = this;
SetPosition(0, 0, 466, 466);
SetStyle(STYLE_BACKGROUND_OPA, 0);
SetDraggable(true);
SetOnDragListener(TjdUiAppSportPresenter::GetInstance());
// InitLabelHorCenter(editTitle_, 28, 17, 466, "编辑运动");
editTitle_.SetFont(TJD_VECTOR_FONT_FILENAME, 28);
editTitle_.SetTextId(STR_ID_207);
// editTitle_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT);
editTitle_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_TOP);
editTitle_.SetPosition(0, 17, 466, 100);
auto editListItemInfo_ = TjdUiAppSportView::GetInstance()->GetEditItemList();
editListAdapterPtr_ =
new TjdUITransformListGroupAdapter<EditItemInfo, EditCaseItemView, std::list<EditItemInfo>>(*editListItemInfo_);
editListView_ = new TjdUITransformListGroup(editListAdapterPtr_);
editListView_->AddCustomView(&editTitle_, TjdUITransformListGroup::CustomViewPos::TOP);
// Add(&editTitle_);
Add(editListView_);
}
EditSportView::~EditSportView()
{
g_pv_EditSportView = nullptr;
RemoveAll();
}
void EditSportView::ShowView()
{
OHOS::FocusManager::GetInstance()->ClearFocus();
editListView_->RequestFocus();
SetVisible(true);
}
void EditSportView::HideView()
{
OHOS::FocusManager::GetInstance()->ClearFocus();
SetVisible(false);
}
EditSportView *EditSportView::GetInstance(void) { return g_pv_EditSportView; }
#pragma endregion
bool GetIfReturnToDial(OHOS::ImageInfo **imgInfo)
{
if (returnToDial) {
*imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(
g_pv_Sport[TjdUiAppSportView::currentIconIndex_].imgIconResId, SPORT_IMAGE_BIN_PATH);
return true;
} else {
*imgInfo = nullptr;
return false;
}
}
#pragma region 321倒计时
#pragma endregion
#pragma region 321倒计时
#pragma endregion
} // namespace TJD