#呼吸训练
${CMAKE_CURRENT_SOURCE_DIR}/nativeui/respiratorytraining/src/RespiratoryTrainingPresenter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/nativeui/respiratorytraining/src/RespiratoryTrainingView.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/respiratorytraining/src/RespiratoryTrainingCompletedView.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/respiratorytraining/src/RespiratoryTrainingModel.cpp
#声音与震动
${CMAKE_CURRENT_SOURCE_DIR}/nativeui/soundandvibration/src/SoundAndVibrationPresenter.cpp
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-08 18:24:24
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-06-11 14:41:30
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingCompletedCompletedView.h
+ */
+
+#ifndef RESPIRATORY_TRAINING_COMPLETED_VIEW_H
+#define RESPIRATORY_TRAINING_COMPLETED_VIEW_H
+
+#include "BaseView.h"
+#include "View.h"
+#include "components/ui_scroll_view.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_label_button_ext.h"
+#include "components/ui_image_view.h"
+
+namespace OHOS
+{
+ static constexpr int MAX_NUM = 3;
+ static constexpr const char *RTCLABELBUTTON = "RTCLabelButton";
+ static constexpr const char *RTCVectorImagePath = "/user/res/RespiratoryTraining/RTCVector.bin";
+ static constexpr const char *RTCGroupListImagePath = "/user/res/RespiratoryTraining/RTCGroupList.bin";
+ class RespiratoryTrainingCompletedView
+ {
+ public:
+ struct LabelConfig
+ {
+ int16_t left;
+ int16_t top;
+ int16_t width;
+ int16_t height;
+ int16_t fontSize; // 字体大小
+ int16_t lineHeigh; // 行高
+ const char *text;
+ int16_t textId;
+ uint8_t lineBreakMode; // 断行模式。
+ };
+
+ struct ImageConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ };
+
+ RespiratoryTrainingCompletedView();
+ ~RespiratoryTrainingCompletedView();
+ static RespiratoryTrainingCompletedView *GetInstance(void);
+ UIScrollView *RespiratoryTrainingCompletedViewInit(void);
+
+ private:
+ void ClearAll(void);
+ bool CreateRespiratoryTrainingCompletedScrollView();
+ bool CreateRespiratoryTrainingCompletedLabelView();
+ bool CreateRespiratoryTrainingCompletedImageView();
+ bool CreateRespiratoryTrainingCompletedLabelButtonView();
+ UILabelExt *LabelExtViewInit(const LabelConfig &labelconfig);
+ UILabel *LabelViewInit(const LabelConfig &labelconfig);
+ UIImageView *ImageViewInit(ImageConfig &imageconfig);
+ UIScrollView *ScrollView{nullptr};
+ UILabelExt *Title{nullptr};
+ UILabelExt *RespiratoryTrainingLabel{nullptr};
+ UIImageView *RespiratoryTrainingImage{nullptr};
+ UILabelExt *RTCStaticLabelView[MAX_NUM]{nullptr};
+ UILabel *RTCDynamicLabelView[MAX_NUM]{nullptr};
+ UIImageView *RTCImageView[MAX_NUM]{nullptr};
+ UILabelButtonExt *RTCLabelButton{nullptr};
+ };
+}
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-11 16:26:13
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-06-12 10:35:46
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingModel.h
+ */
+#ifndef RESPIRATORY_TRAINING_MODEL_H
+#define RESPIRATORY_TRAINING_MODEL_H
+
+#include <cstdint>
+#include <iostream>
+#include "string"
+namespace OHOS
+{
+ class RespiratoryTrainingModel
+ {
+ public:
+ static RespiratoryTrainingModel &GetInstance(void);
+ void AddRespiratoryTrainingTimes(void);
+ std::string GetRespiratoryTrainingTotalTime(void) ;
+ std::string GetHeartRateValue(void) ;
+ void ResumeStatus();
+
+ void RT_StartTimer(uint32_t interval);
+ void RT_StopTimer(void);
+
+ private:
+ RespiratoryTrainingModel();
+ ~RespiratoryTrainingModel();
+ RespiratoryTrainingModel(const RespiratoryTrainingModel &) = delete;
+ RespiratoryTrainingModel &operator=(const RespiratoryTrainingModel &) = delete;
+
+ int RespiratoryTrainingTimes{0}; // 呼吸训练次数
+ std::string RespiratoryTrainingTime{nullptr};
+ std::string HeartRateValue{nullptr};
+ };
+}
+
+#endif
\ No newline at end of file
* @Author: luozheng 1732036298@qq.com
* @Date: 2024-06-08 09:36:01
* @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-08 18:09:42
+ * @LastEditTime: 2024-06-12 10:37:30
* @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingView.h
*/
#include "components/ui_image_view.h"
#include "components/root_view.h"
#include "hal_tick.h"
+#include "components/ui_scroll_view.h"
+#include "respiratorytraining/include/RespiratoryTrainingCompletedView.h"
namespace OHOS
{
+ typedef enum
+ {
+ RESPIRATORYTRAINING = 0,
+ RESPIRATORYTRAININGCOMPLETED,
+ MAX_RESPIRATORYTRAININGID,
+ } RESPIRATORYTRAININGVIEWID;
+
class RespiratoryTrainingCallback : public AnimatorCallback
{
public:
int16_t step = -1;
float scale = 0;
uint16_t curTime = 0;
- uint16_t durationTime = 4*1000; // 4000: means 4000ms
+ uint16_t durationTime = 5 * 1000; // 5000: means 5000ms
int16_t startVal = durationTime;
int16_t endVal = durationTime / 2; // 2: half
};
RespiratoryTrainingView();
virtual ~RespiratoryTrainingView();
static RespiratoryTrainingView *GetInstance(void);
-
+ bool ClickFunc(int16_t interface);
+ void ChangeView(int16_t hideView, int16_t showView);
+ bool ChangeRespiratoryTrainingView(int16_t thisView);
+ bool ChangeRespiratoryTrainingCompletedView(int16_t thisView);
+ Animator *GetRespiratoryTrainingAnimator_();
+ bool StartRespiratoryTraining();
void OnStart() override;
void OnSetUpView() override;
void OnTearDownView() override;
#endif
void InitRespiratoryTrainingElements();
void InitRespiratoryTrainingCallBackAndAnimator();
+ void InitRespiratoryTrainingScrollView();
+ UIScrollView *RespiratoryTrainingScrollView[MAX_RESPIRATORYTRAININGID]{nullptr};
+ RespiratoryTrainingCompletedView *p_RespiratoryTrainingCompletedView{nullptr};
RespiratoryTrainingCallback *RespiratoryTrainingCallBack_ = nullptr;
Animator *RespiratoryTrainingAnimator_ = nullptr;
UIImageView *RespiratoryTrainingImg_ = nullptr;
- UILabelButton *RespiratoryTrainingStart_ = nullptr;
+ //UILabelButton *RespiratoryTrainingStart_ = nullptr;
+ UILabelExt *RespiratoryTrainingStartNote_ = nullptr;
UILabelExt *RespiratoryTrainingLabel_ = nullptr;
bool animateStart_ = false;
};
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-05-07 11:25:58
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-06-12 10:25:32
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/RespiratoryTrainingCompleted/src/RespiratoryTrainingCompletedView.cpp
+ */
+
+#include "respiratorytraining/include/RespiratoryTrainingCompletedView.h"
+#include "wearable_log.h"
+#include "language/font/ui_resource_string.h"
+#include "respiratorytraining/include/RespiratoryTrainingPresenter.h"
+#include "common/image_cache_manager.h"
+#include "respiratorytraining/include/RespiratoryTrainingModel.h"
+
+namespace OHOS
+{
+
+ static RespiratoryTrainingCompletedView *g_pRespiratoryTrainingCompletedView{nullptr};
+
+ RespiratoryTrainingCompletedView::RespiratoryTrainingCompletedView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::RespiratoryTrainingCompletedView");
+ g_pRespiratoryTrainingCompletedView = this;
+ }
+
+ RespiratoryTrainingCompletedView::~RespiratoryTrainingCompletedView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::~RespiratoryTrainingCompletedView");
+ ClearAll();
+ g_pRespiratoryTrainingCompletedView = nullptr;
+ }
+
+ RespiratoryTrainingCompletedView *RespiratoryTrainingCompletedView::GetInstance()
+ {
+ return g_pRespiratoryTrainingCompletedView;
+ }
+
+ void RespiratoryTrainingCompletedView::ClearAll(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::ClearAll Start!!");
+ if (ScrollView != nullptr)
+ {
+ ScrollView->RemoveAll();
+ ImageCacheManager::GetInstance().UnloadSingleRes(RTCVectorImagePath);
+ ImageCacheManager::GetInstance().UnloadSingleRes(RTCGroupListImagePath);
+
+ if (Title != nullptr)
+ {
+ delete Title;
+ Title = nullptr;
+ }
+
+ if (RespiratoryTrainingImage != nullptr)
+ {
+ delete RespiratoryTrainingImage;
+ RespiratoryTrainingImage = nullptr;
+ }
+
+ if (RespiratoryTrainingLabel != nullptr)
+ {
+ delete RespiratoryTrainingLabel;
+ RespiratoryTrainingLabel = nullptr;
+ }
+ for (int i = 0; i < MAX_NUM; i++)
+ {
+ if (RTCStaticLabelView[i] != nullptr)
+ {
+ delete RTCStaticLabelView[i];
+ RTCStaticLabelView[i] = nullptr;
+ }
+
+ if (RTCDynamicLabelView[i] != nullptr)
+ {
+ delete RTCDynamicLabelView[i];
+ RTCDynamicLabelView[i] = nullptr;
+ }
+
+ if (RTCImageView[i] != nullptr)
+ {
+ delete RTCImageView[i];
+ RTCImageView[i] = nullptr;
+ }
+ }
+
+ if (RTCLabelButton != nullptr)
+ {
+ delete RTCLabelButton;
+ RTCLabelButton = nullptr;
+ }
+
+ delete ScrollView;
+ ScrollView = nullptr;
+ }
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::ClearAll End!!");
+ }
+
+ UILabelExt *RespiratoryTrainingCompletedView::LabelExtViewInit(const LabelConfig &labelconfig)
+ {
+ UILabelExt *label = new UILabelExt();
+ if (label == nullptr)
+ {
+ return nullptr;
+ }
+ label->SetPosition(labelconfig.left, labelconfig.top, labelconfig.width, labelconfig.height); // 位置大小
+ label->SetStyle(STYLE_TEXT_FONT, labelconfig.fontSize); // 字体大小
+ label->SetStyle(STYLE_LINE_HEIGHT, labelconfig.lineHeigh); // 字体行高
+ label->SetTextId(labelconfig.textId); // 内容
+ label->SetLineBreakMode(labelconfig.lineBreakMode); // 断行模式。
+ label->SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER);
+ label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize);
+ return label;
+ }
+
+ UILabel *RespiratoryTrainingCompletedView::LabelViewInit(const LabelConfig &labelconfig)
+ {
+ UILabel *label = new UILabel();
+ if (label == nullptr)
+ {
+ return nullptr;
+ }
+ label->SetPosition(labelconfig.left, labelconfig.top, labelconfig.width, labelconfig.height); // 位置大小
+ label->SetStyle(STYLE_TEXT_FONT, labelconfig.fontSize); // 字体大小
+ label->SetStyle(STYLE_LINE_HEIGHT, labelconfig.lineHeigh); // 字体行高
+ label->SetText(labelconfig.text); // 内容
+ label->SetLineBreakMode(labelconfig.lineBreakMode); // 断行模式。
+ label->SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER);
+ label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize);
+ return label;
+ }
+
+ UIImageView *RespiratoryTrainingCompletedView::ImageViewInit(ImageConfig &imageconfig)
+ {
+ UIImageView *Image = new UIImageView();
+ if (Image == nullptr)
+ {
+ return nullptr;
+ }
+ Image->SetPosition(imageconfig.x, imageconfig.y, imageconfig.w, imageconfig.h);
+ return Image;
+ }
+
+ bool RespiratoryTrainingCompletedView::CreateRespiratoryTrainingCompletedScrollView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::CreateRespiratoryTrainingCompletedScrollView");
+ ScrollView = new UIScrollView();
+ if (ScrollView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ScrollView new fail!");
+ return false;
+ }
+ ScrollView->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
+ ScrollView->SetScrollBlankSize(75);
+ ScrollView->SetReboundSize(35);
+ ScrollView->SetHorizontalScrollState(false);
+ ScrollView->SetTouchable(true);
+ ScrollView->SetDraggable(true);
+
+ return true;
+ }
+
+ bool RespiratoryTrainingCompletedView::CreateRespiratoryTrainingCompletedLabelView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::CreateRespiratoryTrainingCompletedLabelView");
+ /* ---------------------------------- Title --------------------------------- */
+ LabelConfig labelconfig = {
+ .left = 83,
+ .top = 52,
+ .width = 300,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = STR_TRAINING_COMPLETE, // 训练完成
+ .lineBreakMode = UILabel::LINE_BREAK_MARQUEE,
+ };
+ Title = LabelExtViewInit(labelconfig);
+ if (nullptr == Title)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Title is nullptr!");
+ return false;
+ }
+ Title->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ ScrollView->Add(Title);
+ /* ------------------------ RespiratoryTrainingLabel ------------------------ */
+ labelconfig.left = 147;
+ labelconfig.top = 150;
+ labelconfig.width = 240;
+ labelconfig.textId = STR_BREATH_TRAINING; // 呼吸训练
+ RespiratoryTrainingLabel = LabelExtViewInit(labelconfig);
+ if (nullptr == RespiratoryTrainingLabel)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingLabel is nullptr!");
+ return false;
+ }
+ ScrollView->Add(RespiratoryTrainingLabel);
+ /* -------------------------------------------------------------------------- */
+ int y1 = 248, y2 = 286;
+ const int textId[MAX_NUM] = {STR_THIS_BREATH, STR_MEAN_HEART_RATE_MIN, STR_TODAYS_BREATHING_TRAINING};
+ std::string heartRateValue = RespiratoryTrainingModel::GetInstance().GetHeartRateValue();
+ std::string trainingTotalTime = RespiratoryTrainingModel::GetInstance().GetRespiratoryTrainingTotalTime();
+ const char *text[MAX_NUM] = {"01:00", heartRateValue.c_str(), trainingTotalTime.c_str()};
+ OHOS::ColorType RTCDynamicLabelTextColor[MAX_NUM] = {
+ Color::GetColorFromRGBA(0x1d, 0xda, 0xc4, 0xff),
+ Color::GetColorFromRGBA(0xff, 0x5a, 0x36, 0xff),
+ Color::GetColorFromRGBA(0xff, 0x8a, 0x36, 0xff),
+ };
+ for (int i = 0; i < MAX_NUM; i++)
+ {
+ labelconfig.left = 138;
+ labelconfig.top = y1 + 130 * i;
+ labelconfig.width = 240;
+ labelconfig.height = 35;
+ labelconfig.fontSize = 30;
+ labelconfig.lineHeigh = 35;
+ labelconfig.textId = textId[i];
+ labelconfig.lineBreakMode = UILabel::LINE_BREAK_MARQUEE;
+ RTCStaticLabelView[i] = LabelExtViewInit(labelconfig);
+ if (nullptr == RTCStaticLabelView[i])
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RTCStaticLabelView[%d] is nullptr!", i);
+ return false;
+ }
+ RTCStaticLabelView[i]->SetTextColor(Color::GetColorFromRGBA(0xff, 0xff, 0xff, 0x7f));
+ ScrollView->Add(RTCStaticLabelView[i]);
+ /* -------------------------------------------------------------------------- */
+ labelconfig.left = 138;
+ labelconfig.top = y2 + 130 * i;
+ labelconfig.height = 47;
+ labelconfig.fontSize = 40;
+ labelconfig.lineHeigh = 47;
+ labelconfig.text = text[i];
+ RTCDynamicLabelView[i] = LabelViewInit(labelconfig);
+ if (nullptr == RTCDynamicLabelView[i])
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RTCDynamicLabelView[%d] is nullptr!", i);
+ return false;
+ }
+ RTCDynamicLabelView[i]->SetTextColor(RTCDynamicLabelTextColor[i]);
+ ScrollView->Add(RTCDynamicLabelView[i]);
+ }
+ return true;
+ }
+
+ bool RespiratoryTrainingCompletedView::CreateRespiratoryTrainingCompletedImageView()
+ {
+ RespiratoryTrainingImage = new UIImageView();
+ if (RespiratoryTrainingImage == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingImage is nullptr!!");
+ return false;
+ }
+ RespiratoryTrainingImage->SetPosition(61, 122, 90, 90);
+ RespiratoryTrainingImage->SetAutoEnable(false);
+ RespiratoryTrainingImage->SetResizeMode(UIImageView::CENTER);
+ ImageInfo *imgInfo = ImageCacheManager::GetInstance().LoadSingleRes(RTCVectorImagePath);
+ if (imgInfo == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Load image failed!");
+ return false;
+ }
+ RespiratoryTrainingImage->SetSrc(imgInfo);
+ ScrollView->Add(RespiratoryTrainingImage);
+ /* -------------------------------------------------------------------------- */
+ ImageConfig imageconfig = {
+ .x = 89,
+ .y = 212,
+ .w = 42,
+ .h = 130,
+ };
+ // 加载呼吸训练Vector图片
+ imgInfo = ImageCacheManager::GetInstance().LoadSingleRes(RTCGroupListImagePath);
+ for (int i = 0; i < MAX_NUM; i++)
+ {
+ imageconfig.y = 212 + (i * 130);
+ RTCImageView[i] = ImageViewInit(imageconfig);
+ if (RTCImageView[i] == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RTCImageView[%d] is nullptr!", i);
+ return false;
+ }
+ RTCImageView[i]->SetSrc(imgInfo);
+ ScrollView->Add(RTCImageView[i]);
+ }
+ return true;
+ }
+
+ bool RespiratoryTrainingCompletedView::CreateRespiratoryTrainingCompletedLabelButtonView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::CreateRespiratoryTrainingCompletedLabelButtonView");
+ RTCLabelButton = new UILabelButtonExt();
+ if (RTCLabelButton == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RTCLabelButton is nullptr!");
+ return false;
+ }
+ RTCLabelButton->SetPosition(43, 622);
+ RTCLabelButton->Resize(380, 100);
+ RTCLabelButton->SetViewId(RTCLABELBUTTON);
+ RTCLabelButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919);
+ // RTCLabelButton->SetText("关闭");
+ RTCLabelButton->SetTextId(STR_CLOSE);
+ RTCLabelButton->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+ RTCLabelButton->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff000000, UIButton::PRESSED);
+ RTCLabelButton->SetStyleForState(STYLE_BORDER_COLOR, 0xffffffff, UIButton::PRESSED);
+ RTCLabelButton->SetStyleForState(STYLE_BORDER_OPA, 0x00, UIButton::PRESSED);
+ UIView::OnClickListener *labelButtonClick = static_cast<UIView::OnClickListener *>(RespiratoryTrainingPresenter::GetInstance());
+ if (labelButtonClick == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "labelButtonClick is nullptr!");
+ return false;
+ }
+ RTCLabelButton->SetOnClickListener(labelButtonClick);
+ ScrollView->Add(RTCLabelButton);
+ return true;
+ }
+
+ // 呼吸训练完成视图初始化
+ UIScrollView *RespiratoryTrainingCompletedView::RespiratoryTrainingCompletedViewInit(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::RespiratoryTrainingCompletedViewInit");
+ if (!CreateRespiratoryTrainingCompletedScrollView() || !CreateRespiratoryTrainingCompletedLabelView() ||
+ !CreateRespiratoryTrainingCompletedImageView() || !CreateRespiratoryTrainingCompletedLabelButtonView())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedViewInit fail!!");
+ return nullptr;
+ }
+ return ScrollView;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-11 16:26:20
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-06-12 11:00:29
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/src/RespiratoryTrainingModel.cpp
+ */
+#include "respiratorytraining/include/RespiratoryTrainingModel.h"
+#include "wearable_log.h"
+#include <cmsis_os2.h>
+#include <cmsis_os.h>
+#include <ohos_types.h>
+#include <service/graphic_service.h>
+#include <iostream>
+#include "respiratorytraining/include/RespiratoryTrainingView.h"
+namespace OHOS
+{
+ // 声明定时器变量
+ static osTimerId_t g_timer = NULL;
+ static int Time = 5;
+ static constexpr int ONE_MINUTE = 60; // 一分钟
+ static bool START_FLAG = false;
+
+ RespiratoryTrainingModel::RespiratoryTrainingModel() {}
+
+ RespiratoryTrainingModel::~RespiratoryTrainingModel() {}
+
+ RespiratoryTrainingModel &RespiratoryTrainingModel::GetInstance()
+ {
+ static RespiratoryTrainingModel instance;
+ return instance;
+ }
+
+ // 每进行一次呼吸训练,呼吸训练次数自加1
+ void RespiratoryTrainingModel::AddRespiratoryTrainingTimes()
+ {
+ RespiratoryTrainingTimes += 1;
+ }
+
+ // 获取呼吸训练总时间
+ std::string RespiratoryTrainingModel::GetRespiratoryTrainingTotalTime(void)
+ {
+ RespiratoryTrainingTime = std::to_string(RespiratoryTrainingTimes) + "min";
+ return RespiratoryTrainingTime;
+ }
+
+ // 获取心率值
+ std::string RespiratoryTrainingModel::GetHeartRateValue(void)
+ {
+ HeartRateValue = "144";
+ return HeartRateValue;
+ }
+
+ void RespiratoryTrainingModel::ResumeStatus()
+ {
+ Time = 5;
+ START_FLAG = false;
+ }
+ /* -------------------------------------------------------------------------- */
+ /*定时器到期时的处理*/
+ static void RT_TimerCallbackProc(int data)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RT_TimerCallbackProc,Time = %d", Time);
+ Time -= 1;
+ RespiratoryTrainingView *p_RespiratoryTrainingView = RespiratoryTrainingView::GetInstance();
+ if (p_RespiratoryTrainingView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "p_RespiratoryTrainingView is nullptr!!");
+ return;
+ }
+ if (Time <= 0)
+ {
+ if (START_FLAG == true)
+ {
+ RespiratoryTrainingModel::GetInstance().RT_StopTimer(); // 停止定时器
+ RespiratoryTrainingModel::GetInstance().AddRespiratoryTrainingTimes();
+ p_RespiratoryTrainingView->GetRespiratoryTrainingAnimator_()->Stop();
+ p_RespiratoryTrainingView->ChangeView(RESPIRATORYTRAINING, RESPIRATORYTRAININGCOMPLETED);
+ }
+ else
+ {
+ Time = ONE_MINUTE;
+ p_RespiratoryTrainingView->StartRespiratoryTraining();
+ START_FLAG = true;
+ }
+ }
+
+ return;
+ }
+
+ /*
+ * @brief 回调函数
+ */
+ static void RT_TimerCallback(int data)
+ {
+ GraphicService::GetInstance()->PostGraphicEvent(std::bind(RT_TimerCallbackProc, data));
+ }
+
+ /*
+ * @brief 开启定时器函数
+ * @param interval 时间间隔,单位ms
+ */
+ void RespiratoryTrainingModel::RT_StartTimer(uint32_t interval)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingModel::RT_StartTimer");
+ /* -------------------------- 1.检查定时器是否已经存在,如果存在则返回 ------------------------- */
+ if (g_timer != NULL)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer already exists!!");
+ return;
+ }
+
+ /* --------------------------------- 2.创建定时器 -------------------------------- */
+ g_timer = osTimerNew((osTimerFunc_t)RT_TimerCallback, osTimerPeriodic, NULL, NULL);
+ // 检查定时器创建是否成功
+ if (g_timer == NULL)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer create failed!!");
+ return;
+ }
+
+ /* ----------------------------- 3.将毫秒转换为系统时钟节拍数 ---------------------------- */
+ int tick = osMs2Tick(interval);
+
+ /* --------------------------------- 4.启动定时器 -------------------------------- */
+ osStatus_t ret = osTimerStart(g_timer, tick);
+ /* -------------------- 5.检查定时器启动是否成功,如果启动失败,删除定时器并置为 NULL -------------------- */
+ if (ret != osOK)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
+ if (g_timer != NULL)
+ {
+ ret = osTimerDelete(g_timer);
+ }
+ g_timer = NULL;
+ return;
+ }
+ }
+
+ /*
+ * @brief 停止定时器
+ */
+ void RespiratoryTrainingModel::RT_StopTimer(void)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingModel::RT_StopTimer");
+ // 检查定时器是否存在
+ if (g_timer != NULL)
+ {
+ // 删除定时器并置为 NULL
+ osStatus_t ret = osTimerDelete(g_timer);
+ if (ret != osOK)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
+ }
+ g_timer = NULL;
+ }
+ }
+}
* @Author: luozheng 1732036298@qq.com
* @Date: 2024-05-07 11:26:06
* @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-08 16:07:50
+ * @LastEditTime: 2024-06-12 11:13:13
* @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/RespiratoryTraining/src/RespiratoryTrainingPresenter.cpp
*/
#include "common/key_code.h"
#include <custom_utils.h>
#include "UiConfig.h"
-
+#include <iostream>
+#include <string>
+#include "respiratorytraining/include/RespiratoryTrainingModel.h"
namespace OHOS
{
{
Presenter<RespiratoryTrainingView>::OnStop();
ScreenAlwaysOnCtr(0);
+ RespiratoryTrainingModel::GetInstance().RT_StopTimer();
+ RespiratoryTrainingModel::GetInstance().ResumeStatus();
}
bool RespiratoryTrainingPresenter::OnClick(UIView &view, const ClickEvent &event)
{
WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingPresenter::OnClick");
+ std::string viewId = view.GetViewId();
+ if(viewId == RTCLABELBUTTON)
+ {
+ NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+ }
return true;
}
* @Author: luozheng 1732036298@qq.com
* @Date: 2024-05-07 11:25:58
* @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-08 17:10:04
+ * @LastEditTime: 2024-06-12 11:09:19
* @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/RespiratoryTraining/src/RespiratoryTrainingView.cpp
*/
#include "common/image_cache_manager.h"
#include "animator/easing_equation.h"
#include "language/font/ui_resource_string.h"
+#include "respiratorytraining/include/RespiratoryTrainingModel.h"
+
namespace OHOS
{
+ static constexpr uint16_t ONE_SECOND = 1000; // 一秒
static RespiratoryTrainingView *g_pRespiratoryTrainingView{nullptr};
RespiratoryTrainingView::RespiratoryTrainingView()
return g_pRespiratoryTrainingView;
}
+ bool RespiratoryTrainingView::ChangeRespiratoryTrainingView(int16_t thisView)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::ChangeRespiratoryTrainingView");
+ if (RespiratoryTrainingScrollView[thisView] == nullptr)
+ {
+ container_->Add(RespiratoryTrainingScrollView[thisView]);
+ }
+ return true;
+ }
+
+ bool RespiratoryTrainingView::ChangeRespiratoryTrainingCompletedView(int16_t thisView)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::ChangeRespiratoryTrainingCompletedView");
+ if (RespiratoryTrainingScrollView[thisView] == nullptr)
+ {
+ p_RespiratoryTrainingCompletedView = new RespiratoryTrainingCompletedView();
+ if (p_RespiratoryTrainingCompletedView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new scrollView[%d] fail", thisView);
+ return false;
+ }
+ RespiratoryTrainingScrollView[thisView] = p_RespiratoryTrainingCompletedView->RespiratoryTrainingCompletedViewInit();
+ container_->Add(RespiratoryTrainingScrollView[thisView]);
+ }
+ return true;
+ }
+
+ struct RespiratoryTrainingViewMapper
+ {
+ const int16_t viewId;
+ bool (RespiratoryTrainingView::*func)(int16_t thisView);
+ };
+
+ static const RespiratoryTrainingViewMapper ViewMapper[] = {
+ {RESPIRATORYTRAINING, &RespiratoryTrainingView::ChangeRespiratoryTrainingView},
+ {RESPIRATORYTRAININGCOMPLETED, &RespiratoryTrainingView::ChangeRespiratoryTrainingCompletedView},
+ };
+
+ // 3.根据传入的interface参数执行相应视图ID关联的成员函数。
+ bool RespiratoryTrainingView::ClickFunc(int16_t interface)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::ClickFunc");
+ int funcSize = sizeof(ViewMapper) / sizeof(ViewMapper[0]);
+ for (int i = 0; i < funcSize; i++)
+ {
+ if (interface == ViewMapper[i].viewId)
+ {
+ bool jug = (this->*(ViewMapper[i].func))(interface);
+ if (jug == false)
+ {
+ return false;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void RespiratoryTrainingView::ChangeView(int16_t hideView, int16_t showView)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::ChangeView");
+ if (hideView > MAX_RESPIRATORYTRAININGID)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Overstep ones bounds");
+ return;
+ }
+ RespiratoryTrainingScrollView[hideView]->SetVisible(false);
+ ClickFunc(showView);
+ RespiratoryTrainingScrollView[showView]->SetVisible(true);
+ Draw();
+ }
+
+ Animator *RespiratoryTrainingView::GetRespiratoryTrainingAnimator_()
+ {
+ if (RespiratoryTrainingAnimator_ == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingAnimator_ is nullptr!!");
+ return nullptr;
+ }
+ return RespiratoryTrainingAnimator_;
+ }
+
// 设置按键监听
static void SetKeyActListener()
{
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetKeyActListener");
RootView::OnKeyActListener *keyactListener = (RootView::OnKeyActListener *)OHOS::RespiratoryTrainingPresenter::GetInstance();
RootView::GetInstance()->SetOnKeyActListener(keyactListener);
}
bool RespiratoryTrainingView::OnClick(UIView &view, const ClickEvent &event)
{
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::OnClick");
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::OnClick");
UNUSED(view);
UNUSED(event);
+#if 0
if (!animateStart_)
{
RespiratoryTrainingAnimator_->Start();
animateStart_ = false;
if (RespiratoryTrainingStart_ != nullptr)
{
- container_->Remove(RespiratoryTrainingStart_);
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Remove(RespiratoryTrainingStart_);
delete RespiratoryTrainingStart_;
RespiratoryTrainingStart_ = nullptr;
}
return false;
}
RespiratoryTrainingLabel_->SetPosition(53, 320, 360, 70); // 180, 380, 100, 50: left, right, width, height
- // RespiratoryTrainingLabel_->SetText("现在呼气气");
+ // RespiratoryTrainingLabel_->SetText("现在呼气");
RespiratoryTrainingLabel_->SetTextId(STR_EXHALE_NOW);
RespiratoryTrainingLabel_->SetStyle(STYLE_TEXT_FONT, 30);
RespiratoryTrainingLabel_->SetStyle(STYLE_LINE_HEIGHT, 35);
RespiratoryTrainingLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
RespiratoryTrainingLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
RespiratoryTrainingLabel_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);
- container_->Add(RespiratoryTrainingLabel_);
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Add(RespiratoryTrainingLabel_);
RespiratoryTrainingCallBack_->SetTextView(RespiratoryTrainingLabel_);
RespiratoryTrainingCallBack_->startTimestamp = HALTick::GetInstance().GetTime();
- container_->Invalidate();
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Invalidate();
}
+#endif
return true;
}
+ // 开始呼吸训练
+ bool RespiratoryTrainingView::StartRespiratoryTraining()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::StartRespiratoryTraining");
+ if (!animateStart_)
+ {
+ RespiratoryTrainingAnimator_->Start();
+ animateStart_ = true;
+ if (RespiratoryTrainingStartNote_ != nullptr)
+ {
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Remove(RespiratoryTrainingStartNote_);
+ delete RespiratoryTrainingStartNote_;
+ RespiratoryTrainingStartNote_ = nullptr;
+ }
+ RespiratoryTrainingLabel_ = new UILabelExt();
+ if (RespiratoryTrainingLabel_ == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingLabel_ new fail");
+ return false;
+ }
+ RespiratoryTrainingLabel_->SetPosition(53, 320, 360, 70);
+ RespiratoryTrainingLabel_->SetTextId(STR_EXHALE_NOW); // 现在呼气
+ RespiratoryTrainingLabel_->SetStyle(STYLE_TEXT_FONT, 30);
+ RespiratoryTrainingLabel_->SetStyle(STYLE_LINE_HEIGHT, 35);
+ RespiratoryTrainingLabel_->SetLineBreakMode(UILabel::LINE_BREAK_WRAP);
+ RespiratoryTrainingLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+ RespiratoryTrainingLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ RespiratoryTrainingLabel_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Add(RespiratoryTrainingLabel_);
+ RespiratoryTrainingCallBack_->SetTextView(RespiratoryTrainingLabel_);
+ RespiratoryTrainingCallBack_->startTimestamp = HALTick::GetInstance().GetTime();
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Invalidate();
+ }
+ return true;
+ }
+
+ // 初始化呼吸训练元素
void RespiratoryTrainingView::InitRespiratoryTrainingElements()
{
WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::InitRespiratoryTrainingElements");
RespiratoryTrainingImg_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);
RespiratoryTrainingImg_->SetAutoEnable(false);
RespiratoryTrainingImg_->SetResizeMode(UIImageView::ImageResizeMode::CENTER);
- container_->Add(RespiratoryTrainingImg_);
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Add(RespiratoryTrainingImg_);
+#if 0
// 创建并设置呼吸训练开始按钮
RespiratoryTrainingStart_ = new UILabelButton();
if (RespiratoryTrainingStart_ == nullptr)
RespiratoryTrainingStart_->SetText("Start");
RespiratoryTrainingStart_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
RespiratoryTrainingStart_->SetOnClickListener(this);
- container_->Add(RespiratoryTrainingStart_);
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Add(RespiratoryTrainingStart_);
+#elif 1
+
+ RespiratoryTrainingStartNote_ = new UILabelExt();
+ if (RespiratoryTrainingStartNote_ == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingStartNote_ new failed!");
+ return;
+ }
+ RespiratoryTrainingStartNote_->SetPosition(53, 320, 360, 70);
+ RespiratoryTrainingStartNote_->SetStyle(STYLE_TEXT_FONT, 30);
+ RespiratoryTrainingStartNote_->SetStyle(STYLE_LINE_HEIGHT, 35);
+ // RespiratoryTrainingStartNote_->SetText("保持不动,将注意力集中在呼吸上");
+ RespiratoryTrainingStartNote_->SetTextId(STR_KEEP_STILL_FOCUS_ON_BREATHING);
+ RespiratoryTrainingStartNote_->SetLineBreakMode(UILabel::LINE_BREAK_WRAP);
+ RespiratoryTrainingStartNote_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ RespiratoryTrainingStartNote_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Add(RespiratoryTrainingStartNote_);
+#endif
}
void RespiratoryTrainingView::InitRespiratoryTrainingCallBackAndAnimator()
animateStart_ = false;
}
+ void RespiratoryTrainingView::InitRespiratoryTrainingScrollView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::CreateRespiratoryTrainingCompletedScrollView");
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING] = new UIScrollView();
+ if (RespiratoryTrainingScrollView[RESPIRATORYTRAINING] == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LanguageSwitchView::ScrollView new fail!");
+ return;
+ }
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->SetScrollBlankSize(50);
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->SetReboundSize(35);
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->SetHorizontalScrollState(false);
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->SetTouchable(true);
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->SetDraggable(true);
+ container_->Add(RespiratoryTrainingScrollView[RESPIRATORYTRAINING]);
+ }
+
void RespiratoryTrainingView::RespiratoryTrainingViewInit(void)
{
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::RespiratoryTrainingViewInit");
+ InitRespiratoryTrainingScrollView();
InitRespiratoryTrainingElements();
InitRespiratoryTrainingCallBackAndAnimator();
+ RespiratoryTrainingModel::GetInstance().RT_StartTimer(ONE_SECOND);
}
void RespiratoryTrainingView::ClearAll(void)
{
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[RespiratoryTrainingView]ClearAll start");
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[RespiratoryTrainingView]ClearAll start");
if (container_ != nullptr)
{
container_->RemoveAll();
container_ = nullptr;
}
+ if (RespiratoryTrainingScrollView[RESPIRATORYTRAINING] != nullptr)
+ {
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->RemoveAll();
+ delete RespiratoryTrainingScrollView[RESPIRATORYTRAINING];
+ RespiratoryTrainingScrollView[RESPIRATORYTRAINING] = nullptr;
+ }
+
if (RespiratoryTrainingAnimator_ != nullptr)
{
RespiratoryTrainingAnimator_->Stop();
delete RespiratoryTrainingLabel_;
RespiratoryTrainingLabel_ = nullptr;
}
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[RespiratoryTrainingView]ClearAll end!!");
+
+ if (p_RespiratoryTrainingCompletedView != nullptr)
+ {
+ delete p_RespiratoryTrainingCompletedView;
+ p_RespiratoryTrainingCompletedView = nullptr;
+
+ RespiratoryTrainingScrollView[RESPIRATORYTRAININGCOMPLETED] = nullptr;
+ }
+
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[RespiratoryTrainingView]ClearAll end!!");
}
void RespiratoryTrainingView::OnStart()
--- /dev/null
+version https://git-lfs.github.com/spec/v1
+oid sha256:15470adf52f28d869bfc75426d39f2fc911113095200d019de832796160a5b71
+size 4776
--- /dev/null
+version https://git-lfs.github.com/spec/v1
+oid sha256:22262add581a16dbb792eb87ace656dcefe6befd7fa4d13fe893728028e26208
+size 1896
version https://git-lfs.github.com/spec/v1
-oid sha256:c04df592f1983b48be8ea953fc16aeb299371367c2ef44b0526a8f0801124def
+oid sha256:96216f711924bb5ef1774a35de2a673b88e5adc4734789d55fec43642697b900
size 38424