添加呼吸训练Slice,还需优化
authorluozheng <1732036298@qq.com>
Sat, 8 Jun 2024 10:11:14 +0000 (18:11 +0800)
committerluozheng <1732036298@qq.com>
Sat, 8 Jun 2024 10:11:14 +0000 (18:11 +0800)
13 files changed:
code/sdk/application/wearable/fd230app/CMakeLists.txt
code/sdk/application/wearable/fd230app/nativelauncher/include/AppViewIDs.h
code/sdk/application/wearable/fd230app/nativelauncher/include/NativeLauncher.h
code/sdk/application/wearable/fd230app/nativelauncher/include/UiConfig.h
code/sdk/application/wearable/fd230app/nativelauncher/src/NativeLauncher.cpp
code/sdk/application/wearable/fd230app/nativeui/applist/src/ApplistModel.cpp
code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingPresenter.h [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/src/RespiratoryTrainingPresenter.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/src/RespiratoryTrainingView.cpp [new file with mode: 0644]
code/sdk/application/wearable/ohos_startup/ohosfwk_startup.c
code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/RespiratoryTraining/RespiratoryTraining.bin [new file with mode: 0644]
code/sdk/drivers/peripheral/utils/custom_utils.c

index fcc105a..6f4c9e5 100644 (file)
@@ -369,6 +369,10 @@ set(SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/watchQRcode/src/WatchQRCodePresenter.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/watchQRcode/src/WatchQRCodeView.cpp
 
+    #呼吸训练
+    ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/respiratorytraining/src/RespiratoryTrainingPresenter.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/respiratorytraining/src/RespiratoryTrainingView.cpp
+
     #声音与震动
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/soundandvibration/src/SoundAndVibrationPresenter.cpp 
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/soundandvibration/src/SoundAndVibrationView.cpp
index 4904b54..5714792 100644 (file)
@@ -63,6 +63,7 @@ typedef enum : uint16_t
     VIEW_MOTION_RECOGNITION,        // 运动识别
     VIEW_SYSTEM_UPDATE,             // 系统更新
     VIEW_WATCH_QR_CODE,             //手表二维码
+    VIEW_RESPIRATORY_TRAINING,      //呼吸训练
     /* ----------------------------------- 录音 ----------------------------------- */
     VIEW_RECORD,
     /* ---------------------------------- 界面 ---------------------------------- */
index eb201cf..94e1890 100644 (file)
@@ -59,6 +59,7 @@ namespace OHOS
         void InitMotionRecognitionSlice(void);
         void InitSystemUpdateSlice(void);
         void InitWatchQRCodeSlice(void);
+        void InitRespiratoryTrainingSlice(void);
         /* --------------------------------界面------------------------------------ */
         void InitRotateSlice(void);
         void InitBloodSlice(void);
index c0b2c91..812f88c 100644 (file)
@@ -266,6 +266,7 @@ namespace OHOS
     static constexpr const char *PNG_APPLIST_MESSAGE_IMAGE = APP_LIST_PATH "/message.bin";          // 消息通知
     static constexpr const char *PNG_APPLIST_TACKEPHOTOS_IMAGE = APP_LIST_PATH "/assistant.bin";    // 遥控拍照
     static constexpr const char *PNG_APPLIST_BLUETOOTH_IMAGE = APP_LIST_PATH "/Bluetooth.bin";      // 蓝牙
+    static constexpr const char *PNG_APPLIST_BREATHE_IMAGE = APP_LIST_PATH "/breathe.bin";          // 呼吸训练
     /* ---------------------------------- 快速训练 ---------------------------------- */
     static constexpr const char *PNG_TRAING_BOUTTONMORE_IMAGE = APP_RES_PATH "/Training/More.bin";
     static constexpr const char *PNG_TRAING_BUTTONGRONG_IMAGE = APP_RES_PATH "/Training/Bouttonground.bin";
index 4369eff..fcf319d 100644 (file)
 
 #include "watchQRcode/include/WatchQRCodePresenter.h"
 #include "watchQRcode/include/WatchQRCodeView.h"
+
+#include "respiratorytraining/include/RespiratoryTrainingPresenter.h"
+#include "respiratorytraining/include/RespiratoryTrainingView.h"
 /* -------------------------------------------------------------------------- */
 #include "traing/include/TraingView.h"
 #include "traing/include/TraingPresenter.h"
@@ -271,6 +274,7 @@ namespace OHOS
         {VIEW_MOTION_RECOGNITION, &NativeLauncher::InitMotionRecognitionSlice},              // 网络与通话
         {VIEW_SYSTEM_UPDATE, &NativeLauncher::InitSystemUpdateSlice},                        // 系统更新界面
         {VIEW_WATCH_QR_CODE, &NativeLauncher::InitWatchQRCodeSlice},                         // 手表二维码界面
+        {VIEW_RESPIRATORY_TRAINING, &NativeLauncher::InitRespiratoryTrainingSlice},          // 呼吸训练界面
 
         // {VIEW_SECONDARY_FUNCTION, &NativeLauncher::InitSecondaryFunction},
         // {VIEW_FAST_TRAINING, &NativeLauncher::InitFastTrainingSlice},
@@ -1176,6 +1180,18 @@ namespace OHOS
         }
         NativeAbility::GetInstance().AddSliceProxy(VIEW_WATCH_QR_CODE, watchqrcode);
     }
+
+    /*呼吸训练*/
+    void NativeLauncher::InitRespiratoryTrainingSlice(void)
+    {
+        SliceProxy *respiratorytraining = new AbilitySliceProxy<RespiratoryTrainingView, RespiratoryTrainingPresenter>;
+        if (respiratorytraining == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "respiratorytraining");
+            return;
+        }
+        NativeAbility::GetInstance().AddSliceProxy(VIEW_RESPIRATORY_TRAINING, respiratorytraining);
+    }
     /* -------------------------------------------------------------------------- */
     void NativeLauncher::InitSetDesktopSlice(void)
     {
index 6fce662..69fd85c 100644 (file)
@@ -47,6 +47,7 @@ namespace OHOS
         {VIEW_SAVEELE, PNG_APPLIST_SAVEELE_IMAGE, PNG_APPLIST_SAVEELE_IMAGE, "省电模式", STR_POWER_SAVE_MODE, nullptr},
         {VIEW_MESSAGE, PNG_APPLIST_MESSAGE_IMAGE, PNG_APPLIST_MESSAGE_IMAGE, "消息通知", STR_MESSAGE_NOTIFICATION, nullptr},
         {VIEW_TAKEPHOTOS, PNG_APPLIST_TACKEPHOTOS_IMAGE, PNG_APPLIST_TACKEPHOTOS_IMAGE, "遥控拍照", STR_REMOTE_SHOOTING, nullptr},
+        {VIEW_RESPIRATORY_TRAINING, PNG_APPLIST_BREATHE_IMAGE, PNG_APPLIST_BREATHE_IMAGE, "呼吸训练", STR_BREATH_TRAINING, nullptr},
 #ifdef SUPPORT_ALIPAY_SEC
         {VIEW_MAIN_ALIPAY, PNG_APPLIST_ALIPAY_IMAGE, PNG_APPLIST_ALIPAY_IMAGE, "支付宝", STR_ALIPAY, nullptr},
 #endif
diff --git a/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingPresenter.h b/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingPresenter.h
new file mode 100644 (file)
index 0000000..c1fd994
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-08 09:36:33
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-06-08 11:00:44
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingPresenter.h
+ */
+
+#ifndef RESPIRATORY_TRAINING_PRESENTER_H
+#define RESPIRATORY_TRAINING_PRESENTER_H
+
+#include "Presenter.h"
+#include "View.h"
+
+namespace OHOS
+{
+
+    class RespiratoryTrainingView;
+    class RespiratoryTrainingPresenter : public Presenter<RespiratoryTrainingView>,
+                                         public UIView::OnClickListener,
+                                         public RootView::OnKeyActListener,
+                                         public UIView::OnDragListener
+    {
+    public:
+        RespiratoryTrainingPresenter();
+        virtual ~RespiratoryTrainingPresenter();
+
+        void OnStart() override;
+        void OnPause() override;
+        void OnResume() override;
+        void OnStop() override;
+
+        static RespiratoryTrainingPresenter *GetInstance();
+
+    private:
+        bool OnClick(UIView &view, const ClickEvent &event) override;
+        bool OnDrag(UIView &view, const DragEvent &event) override;
+        bool OnDragEnd(UIView &view, const DragEvent &event) override;
+        bool OnKeyAct(UIView &view, const KeyEvent &event) override; // 增加按键事件
+
+        bool X_DRAG_FLAG{false};
+    };
+}
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingView.h b/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingView.h
new file mode 100644 (file)
index 0000000..99acee8
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-08 09:36:01
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-06-08 18:09:42
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingView.h
+ */
+
+#ifndef RESPIRATORY_TRAINING_VIEW_H
+#define RESPIRATORY_TRAINING_VIEW_H
+
+#include "BaseView.h"
+#include "View.h"
+#include "components/ui_label_ext.h"
+#include <components/ui_label_button_ext.h>
+#include "components/ui_image_animator.h"
+#include "components/ui_image_view.h"
+#include "components/root_view.h"
+#include "hal_tick.h"
+
+namespace OHOS
+{
+    class RespiratoryTrainingCallback : public AnimatorCallback
+    {
+    public:
+        explicit RespiratoryTrainingCallback(UIImageView *img) : img_(img) {}
+        ~RespiratoryTrainingCallback() override {}
+        void Callback(UIView *view) override;
+        void SetTextView(UILabelExt *view)
+        {
+            breath = view;
+        }
+
+        uint32_t startTimestamp = 0;
+
+    private:
+        UIImageView *img_ = nullptr;
+        UILabelExt *breath = nullptr;
+        bool isBreathIn = false;
+        int16_t angle = 0;
+        int16_t step = -1;
+        float scale = 0;
+        uint16_t curTime = 0;
+        uint16_t durationTime = 4*1000; // 4000: means 4000ms
+        int16_t startVal = durationTime;
+        int16_t endVal = durationTime / 2; // 2: half
+    };
+
+    static constexpr int RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_X = 193;
+    static constexpr int RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_Y = 110;
+    static constexpr int RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_W = 80;
+    static constexpr int RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_H = 80;
+    static constexpr int RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_TIMEOFUPDATE = 100;
+    static constexpr int RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES = 25; // 呼吸训练动画帧数
+    static ImageAnimatorInfo RespiratoryTrainingImageInfo[RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES];
+
+    class RespiratoryTrainingPresenter;
+    class RespiratoryTrainingView : public View<RespiratoryTrainingPresenter>, public UIView::OnClickListener
+    {
+
+    public:
+        RespiratoryTrainingView();
+        virtual ~RespiratoryTrainingView();
+        static RespiratoryTrainingView *GetInstance(void);
+
+        void OnStart() override;
+        void OnSetUpView() override;
+        void OnTearDownView() override;
+        void OnStop() override;
+
+        bool OnClick(UIView &view, const ClickEvent &event) override;
+
+    private:
+        void RespiratoryTrainingViewInit(void);
+        void ClearAll(void);
+#if 0
+        const char **CreateImagePathsArray(const char *basePath, const char *fileExtension, int numImages);
+        void FreeImagePathsArray(const char **imagePaths, const int numImages);
+        void InitializeRespiratoryTrainingImageInfo();
+        void SetAnimatorViewProperties();
+        void CreateRespiratoryTrainingAnimatorView();
+        void CreateRespiratoryTrainingLabelView();
+        void SetLabelViewProperties();
+        UILabelExt *RespiratoryTrainingLabelView{nullptr};
+        UIImageAnimatorView *RespiratoryTrainingAnimatorView{nullptr}; // 呼吸训练动画
+        const char **RespiratoryTrainingArray{nullptr};
+#endif
+        void InitRespiratoryTrainingElements();
+        void InitRespiratoryTrainingCallBackAndAnimator();
+        RespiratoryTrainingCallback *RespiratoryTrainingCallBack_ = nullptr;
+        Animator *RespiratoryTrainingAnimator_ = nullptr;
+        UIImageView *RespiratoryTrainingImg_ = nullptr;
+        UILabelButton *RespiratoryTrainingStart_ = nullptr;
+        UILabelExt *RespiratoryTrainingLabel_ = nullptr;
+        bool animateStart_ = false;
+    };
+
+}
+#endif
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/src/RespiratoryTrainingPresenter.cpp b/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/src/RespiratoryTrainingPresenter.cpp
new file mode 100644 (file)
index 0000000..a1f9778
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-05-07 11:26:06
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-06-08 16:07:50
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/RespiratoryTraining/src/RespiratoryTrainingPresenter.cpp
+ */
+
+#include "AppViewIDs.h"
+#include "NativeAbility.h"
+#include "respiratorytraining/include/RespiratoryTrainingPresenter.h"
+#include "respiratorytraining/include/RespiratoryTrainingView.h"
+#include "common/key_code.h"
+#include <custom_utils.h>
+#include "UiConfig.h"
+
+namespace OHOS
+{
+
+    // 当前Presenter属性实例化的内存指针
+    static RespiratoryTrainingPresenter *g_pRespiratoryTrainingPresenter = nullptr;
+
+    RespiratoryTrainingPresenter::RespiratoryTrainingPresenter()
+    {
+        g_pRespiratoryTrainingPresenter = this;
+    }
+
+    RespiratoryTrainingPresenter::~RespiratoryTrainingPresenter()
+    {
+        g_pRespiratoryTrainingPresenter = nullptr;
+    }
+
+    RespiratoryTrainingPresenter *RespiratoryTrainingPresenter::GetInstance()
+    {
+        return g_pRespiratoryTrainingPresenter;
+    }
+
+    void RespiratoryTrainingPresenter::OnStart()
+    {
+        Presenter<RespiratoryTrainingView>::OnStart();
+        ScreenAlwaysOnCtr(1);
+    }
+
+    void RespiratoryTrainingPresenter::OnPause(void)
+    {
+        Presenter<RespiratoryTrainingView>::OnPause();
+    }
+
+    void RespiratoryTrainingPresenter::OnResume(void)
+    {
+        Presenter<RespiratoryTrainingView>::OnResume();
+    }
+
+    void RespiratoryTrainingPresenter::OnStop(void)
+    {
+        Presenter<RespiratoryTrainingView>::OnStop();
+        ScreenAlwaysOnCtr(0);
+    }
+
+    bool RespiratoryTrainingPresenter::OnClick(UIView &view, const ClickEvent &event)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingPresenter::OnClick");
+        return true;
+    }
+
+    bool RespiratoryTrainingPresenter::OnDrag(UIView &view, const DragEvent &event)
+    {
+        UNUSED(view);
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingPresenter::OnDrag");
+        if ((event.GetDeltaX() > X_DRAG_OFFSET) && (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) // 拖动过程中判断是否是水平滑动
+        {
+            RespiratoryTrainingPresenter::X_DRAG_FLAG = true;
+        }
+        return true;
+    }
+
+    bool RespiratoryTrainingPresenter::OnDragEnd(UIView &view, const DragEvent &event)
+    {
+        UNUSED(view);
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingPresenter::OnDragEnd");
+        if (event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT && RespiratoryTrainingPresenter::X_DRAG_FLAG)
+        {
+            NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+            RespiratoryTrainingPresenter::X_DRAG_FLAG = false;
+        }
+        return true;
+    }
+
+    bool RespiratoryTrainingPresenter::OnKeyAct(UIView &view, const KeyEvent &event) // 增加按键事件
+    {
+        UNUSED(view);
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingPresenter::OnKeyAct");
+        uint16_t keyID = event.GetKeyId();
+        uint16_t keyState = event.GetState();
+        // 如果是power键,且是亮屏状态,按键释放就返回上一级
+        if (keyID == static_cast<uint16_t>(ZliteKeyCode::ZLITE_KEY_POWER) && keyState == 0 && uapi_get_screen_state() == 0)
+        {
+            NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+        }
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/src/RespiratoryTrainingView.cpp b/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/src/RespiratoryTrainingView.cpp
new file mode 100644 (file)
index 0000000..66d8dc9
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-05-07 11:25:58
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-06-08 17:10:04
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/RespiratoryTraining/src/RespiratoryTrainingView.cpp
+ */
+
+#include "respiratorytraining/include/RespiratoryTrainingPresenter.h"
+#include "respiratorytraining/include/RespiratoryTrainingView.h"
+#include "wearable_log.h"
+#include "common/image_cache_manager.h"
+#include "animator/easing_equation.h"
+#include "language/font/ui_resource_string.h"
+namespace OHOS
+{
+
+    static RespiratoryTrainingView *g_pRespiratoryTrainingView{nullptr};
+
+    RespiratoryTrainingView::RespiratoryTrainingView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::RespiratoryTrainingView");
+        g_pRespiratoryTrainingView = this;
+    }
+
+    RespiratoryTrainingView::~RespiratoryTrainingView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::~RespiratoryTrainingView");
+        g_pRespiratoryTrainingView = nullptr;
+    }
+
+    RespiratoryTrainingView *RespiratoryTrainingView::GetInstance()
+    {
+        return g_pRespiratoryTrainingView;
+    }
+
+    // 设置按键监听
+    static void SetKeyActListener()
+    {
+        RootView::OnKeyActListener *keyactListener = (RootView::OnKeyActListener *)OHOS::RespiratoryTrainingPresenter::GetInstance();
+        RootView::GetInstance()->SetOnKeyActListener(keyactListener);
+    }
+
+#if 0
+    void RespiratoryTrainingView::ClearAll(void)
+    {
+        if (container_ != nullptr)
+        {
+            container_->RemoveAll();
+            delete container_;
+            container_ = nullptr;
+        }
+
+        if (RespiratoryTrainingAnimator_ != nullptr)
+        {
+            RespiratoryTrainingAnimator_->Stop();
+            delete RespiratoryTrainingAnimator_;
+            RespiratoryTrainingAnimator_ = nullptr;
+        }
+
+        if (RespiratoryTrainingCallBack_ != nullptr)
+        {
+            delete RespiratoryTrainingCallBack_;
+            RespiratoryTrainingCallBack_ = nullptr;
+        }
+
+        if (RespiratoryTrainingImg_ != nullptr)
+        {
+            ImageCacheManager::GetInstance().UnloadSingleRes(RespiratoryTrainingImagePath);
+            delete RespiratoryTrainingImg_;
+            RespiratoryTrainingImg_ = nullptr;
+        }
+
+        if (RespiratoryTrainingLabel_ != nullptr)
+        {
+            delete RespiratoryTrainingLabel_;
+            RespiratoryTrainingLabel_ = nullptr;
+        }
+    }
+
+    const char **RespiratoryTrainingView::CreateImagePathsArray(const char *basePath, const char *fileExtension, int numImages)
+    {
+        const char **imagePaths = new const char *[numImages];
+        char buffer[256];
+        for (int i = 0; i < numImages; i++)
+        {
+            snprintf(buffer, sizeof(buffer), "%s%d.%s", basePath, i + 1, fileExtension);
+            imagePaths[i] = strdup(buffer);
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " imagePaths[%d] = %s", i, imagePaths[i]);
+        }
+        return imagePaths;
+    }
+    /*
+     * @brief: 释放图片路径数组指针
+     * @param {char} imagePaths 图片路径数组
+     * @param {int} numImages 图片数量
+     */
+    void RespiratoryTrainingView::FreeImagePathsArray(const char **imagePaths, const int numImages)
+    {
+        for (int i = 0; i < numImages; i++)
+        {
+            delete imagePaths[i];
+            imagePaths[i] = nullptr;
+        }
+    }
+
+    // 初始化呼吸训练动画图片信息
+    void RespiratoryTrainingView::InitializeRespiratoryTrainingImageInfo()
+    {
+        for (uint8_t i = 0; i < RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES; i++)
+        {
+            RespiratoryTrainingImageInfo[i].imagePath = (RespiratoryTrainingArray[i]);
+            RespiratoryTrainingImageInfo[i].imageType = RespiratoryTrainingImg_SRC_FILE_PATH;
+            RespiratoryTrainingImageInfo[i].pos.x = RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_X;
+            RespiratoryTrainingImageInfo[i].pos.y = RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_Y;
+            RespiratoryTrainingImageInfo[i].width = RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_W;
+            RespiratoryTrainingImageInfo[i].height = RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_H;
+        }
+    }
+
+    // 设置动画属性
+    void RespiratoryTrainingView::SetAnimatorViewProperties()
+    {
+        RespiratoryTrainingAnimatorView->SetPosition(RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_X, RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_Y);
+        RespiratoryTrainingAnimatorView->Resize(RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_W, RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_H);
+        RespiratoryTrainingAnimatorView->SetStyle(STYLE_BACKGROUND_COLOR, 0xffffffff);
+        RespiratoryTrainingAnimatorView->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+        RespiratoryTrainingAnimatorView->SetImageAnimatorSrc(RespiratoryTrainingImageInfo, RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES, RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_TIMEOFUPDATE);
+        RespiratoryTrainingAnimatorView->SetRepeat(true);
+        RespiratoryTrainingAnimatorView->Start();
+    }
+
+    // 创建呼吸训练动画视图
+    void RespiratoryTrainingView::CreateRespiratoryTrainingAnimatorView()
+    {
+        RespiratoryTrainingArray = RespiratoryTrainingView::GetInstance()->CreateImagePathsArray("/user/res/remind/RESPIRATORY_TRAINING_/", "bin", RESPIRATORY_TRAINING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES);
+
+        if (RespiratoryTrainingAnimatorView == nullptr)
+        {
+            RespiratoryTrainingAnimatorView = new UIImageAnimatorView();
+            if (RespiratoryTrainingAnimatorView == nullptr)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CreateDeviceRESPIRATORY_TRAINING_ingView]RespiratoryTrainingAnimatorView new fail");
+                return;
+            }
+
+            InitializeRespiratoryTrainingImageInfo();
+            SetAnimatorViewProperties();
+        }
+    }
+
+    // 创建呼吸训练标签视图
+    void RespiratoryTrainingView::CreateRespiratoryTrainingLabelView()
+    {
+        if (RespiratoryTrainingLabelView == nullptr)
+        {
+            RespiratoryTrainingLabelView = new UILabelExt();
+            if (RespiratoryTrainingLabelView == nullptr)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CreateDeviceRESPIRATORY_TRAINING_ingView]RespiratoryTrainingLabelView new fail");
+                return;
+            }
+            SetLabelViewProperties();
+        }
+    }
+
+    void RespiratoryTrainingView::SetLabelViewProperties()
+    {
+        RespiratoryTrainingLabelView->SetPosition(83, 320, 360, 70);
+    }
+
+    void RespiratoryTrainingView::RespiratoryTrainingViewInit(void)
+    {
+        CreateRespiratoryTrainingAnimatorView();
+        CreateRespiratoryTrainingLabelView();
+    }
+#endif
+
+    const static int16_t BUTTON_WIDTH = 320;
+    const static int16_t BUTTON_HEIGHT = 100;
+    const static int16_t INTERVAL_STEP = 80;
+    const Vector2<float> VIEW_CENTER = {120, 120};
+    static constexpr const char *RespiratoryTrainingImagePath = "/user/res/RespiratoryTraining/RespiratoryTraining.bin";
+
+    void RespiratoryTrainingCallback::Callback(UIView *view)
+    {
+        // 1.计算当前时间与开始时间的差值,用于控制动画的时间。
+        curTime = HALTick::GetInstance().GetTime() - startTimestamp;
+        // 2.判断当前时间是否大于等于训练总时长,若是则进行下一步操作,否则继续进行呼吸动画的变化。
+        if (curTime >= durationTime)
+        {
+            // 计算动画缩放比例,根据呼吸的起始值、结束值、当前时间、总时间和缓动函数 QuadEaseInOut 进行计算。
+            curTime = durationTime;
+            scale =
+                static_cast<float>(EasingEquation::QuadEaseInOut(startVal, endVal, curTime, durationTime)) / durationTime;
+            // 切换起始值和结束值,更新下一次呼吸的状态。
+            int16_t temp = startVal;
+            startVal = endVal;
+            endVal = temp;
+            startTimestamp = HALTick::GetInstance().GetTime();
+            isBreathIn = !isBreathIn;
+            if (isBreathIn)
+            {
+                // breath->SetText("现在吸气");
+                breath->SetTextId(STR_INHALE_NOW);
+            }
+            else
+            {
+                // breath->SetText("现在呼气");
+                breath->SetTextId(STR_EXHALE_NOW);
+            }
+            breath->ForceResetText();
+        }
+        else
+        {
+            scale =
+                static_cast<float>(EasingEquation::QuadEaseInOut(startVal, endVal, curTime, durationTime)) / durationTime;
+        }
+        // 根据动画步长 step 更新图片的旋转角度 angle,每次旋转完成后将角度重置为 0,实现连续旋转效果。
+        angle += step;
+        if (angle <= -360)
+        { // 360: degrees per cycle
+            angle = 0;
+        }
+        // 根据计算得到的缩放比例 scale 对图片进行缩放操作,并根据角度对图片进行旋转操作
+        img_->Scale({scale, scale}, VIEW_CENTER);
+        img_->Rotate(angle, VIEW_CENTER);
+        img_->Invalidate();
+    }
+
+    bool RespiratoryTrainingView::OnClick(UIView &view, const ClickEvent &event)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::OnClick");
+        UNUSED(view);
+        UNUSED(event);
+        if (!animateStart_)
+        {
+            RespiratoryTrainingAnimator_->Start();
+            animateStart_ = false;
+            if (RespiratoryTrainingStart_ != nullptr)
+            {
+                container_->Remove(RespiratoryTrainingStart_);
+                delete RespiratoryTrainingStart_;
+                RespiratoryTrainingStart_ = nullptr;
+            }
+            RespiratoryTrainingLabel_ = new UILabelExt();
+            if (RespiratoryTrainingLabel_ == nullptr)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingLabel_ new fail");
+                return false;
+            }
+            RespiratoryTrainingLabel_->SetPosition(53, 320, 360, 70); // 180, 380, 100, 50: left, right, width, height
+            // RespiratoryTrainingLabel_->SetText("现在呼气气");
+            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);
+            container_->Add(RespiratoryTrainingLabel_);
+            RespiratoryTrainingCallBack_->SetTextView(RespiratoryTrainingLabel_);
+            RespiratoryTrainingCallBack_->startTimestamp = HALTick::GetInstance().GetTime();
+            container_->Invalidate();
+        }
+        return true;
+    }
+
+    void RespiratoryTrainingView::InitRespiratoryTrainingElements()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::InitRespiratoryTrainingElements");
+        // 加载呼吸训练图片
+        ImageInfo *imgInfo = ImageCacheManager::GetInstance().LoadSingleRes(RespiratoryTrainingImagePath);
+        if (imgInfo == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Load image failed!");
+            return;
+        }
+
+        // 创建并设置呼吸训练图片
+        RespiratoryTrainingImg_ = new UIImageView();
+        if (RespiratoryTrainingImg_ == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingImg_ new failed!");
+            return;
+        }
+        RespiratoryTrainingImg_->SetSrc(imgInfo);
+        RespiratoryTrainingImg_->SetPosition(113, 70, 240, 240);
+        RespiratoryTrainingImg_->SetStyle(STYLE_IMAGE_OPA, OPA_OPAQUE);
+        RespiratoryTrainingImg_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);
+        RespiratoryTrainingImg_->SetAutoEnable(false);
+        RespiratoryTrainingImg_->SetResizeMode(UIImageView::ImageResizeMode::CENTER);
+        container_->Add(RespiratoryTrainingImg_);
+
+        // 创建并设置呼吸训练开始按钮
+        RespiratoryTrainingStart_ = new UILabelButton();
+        if (RespiratoryTrainingStart_ == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingStart_ new failed!");
+            return;
+        }
+        RespiratoryTrainingStart_->SetPosition(158, 320, 150, 75);
+        RespiratoryTrainingStart_->SetText("Start");
+        RespiratoryTrainingStart_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+        RespiratoryTrainingStart_->SetOnClickListener(this);
+        container_->Add(RespiratoryTrainingStart_);
+    }
+
+    void RespiratoryTrainingView::InitRespiratoryTrainingCallBackAndAnimator()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::InitRespiratoryTrainingCallBackAndAnimator");
+        RespiratoryTrainingCallBack_ = new RespiratoryTrainingCallback(RespiratoryTrainingImg_);
+        if (RespiratoryTrainingCallBack_ == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "callBack new fail");
+            return;
+        }
+
+        RespiratoryTrainingAnimator_ = new Animator(RespiratoryTrainingCallBack_, RespiratoryTrainingImg_, 0, true);
+        if (RespiratoryTrainingAnimator_ == nullptr)
+        {
+            delete RespiratoryTrainingCallBack_;
+            RespiratoryTrainingCallBack_ = nullptr;
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Animator new fail");
+            return;
+        }
+
+        animateStart_ = false;
+    }
+
+    void RespiratoryTrainingView::RespiratoryTrainingViewInit(void)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::RespiratoryTrainingViewInit");
+        InitRespiratoryTrainingElements();
+        InitRespiratoryTrainingCallBackAndAnimator();
+    }
+
+    void RespiratoryTrainingView::ClearAll(void)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[RespiratoryTrainingView]ClearAll start");
+        if (container_ != nullptr)
+        {
+            container_->RemoveAll();
+            delete container_;
+            container_ = nullptr;
+        }
+
+        if (RespiratoryTrainingAnimator_ != nullptr)
+        {
+            RespiratoryTrainingAnimator_->Stop();
+            delete RespiratoryTrainingAnimator_;
+            RespiratoryTrainingAnimator_ = nullptr;
+        }
+
+        if (RespiratoryTrainingCallBack_ != nullptr)
+        {
+            delete RespiratoryTrainingCallBack_;
+            RespiratoryTrainingCallBack_ = nullptr;
+        }
+
+        if (RespiratoryTrainingImg_ != nullptr)
+        {
+            ImageCacheManager::GetInstance().UnloadSingleRes(RespiratoryTrainingImagePath);
+            delete RespiratoryTrainingImg_;
+            RespiratoryTrainingImg_ = nullptr;
+        }
+
+        if (RespiratoryTrainingLabel_ != nullptr)
+        {
+            delete RespiratoryTrainingLabel_;
+            RespiratoryTrainingLabel_ = nullptr;
+        }
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[RespiratoryTrainingView]ClearAll end!!");
+    }
+
+    void RespiratoryTrainingView::OnStart()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::OnStart");
+        View<RespiratoryTrainingPresenter>::OnStart();
+        SetContainerView(new UIViewGroup());
+        container_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
+        container_->SetOnDragListener(presenter_);
+        container_->SetTouchable(true);
+        container_->SetDraggable(true);
+
+        RespiratoryTrainingViewInit();
+        SetKeyActListener();
+    }
+
+    void RespiratoryTrainingView::OnSetUpView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::OnSetUpView");
+        View<RespiratoryTrainingPresenter>::OnSetUpView();
+        Draw();
+    }
+
+    void RespiratoryTrainingView::OnTearDownView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::OnTearDownView");
+        View<RespiratoryTrainingPresenter>::OnTearDownView();
+        return;
+    }
+
+    void RespiratoryTrainingView::OnStop()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::OnStop");
+        View<RespiratoryTrainingPresenter>::OnStop();
+        RootView::GetInstance()->ClearOnKeyActListener();
+        ClearAll();
+        return;
+    }
+}
\ No newline at end of file
index 084c529..f2e077c 100755 (executable)
@@ -78,16 +78,16 @@ void ohos_startup()
     mount_user_res_partition();
 #endif
 
-#ifdef SUPPORT_POWER_MANAGER
-    // const power_display_svr_api_t *display_api = power_display_svr_get_api();
-    // display_api->turn_on_screen();
-    display_api->set_screen_set_keepon_timeout(5000);
-#endif
-
-
 #if defined(CONFIG_OTA_UPDATE_SUPPORT) && defined(ENABLE_UIKIT)
     //如果在升级状态,则不进入系统
  if  (upg_check_upgrade_need_upgrade()) return ;
 #endif
     OHOS_SystemInit();
+    
+#ifdef SUPPORT_POWER_MANAGER
+    // const power_display_svr_api_t *display_api = power_display_svr_get_api();
+    // display_api->turn_on_screen();
+    display_api->set_screen_set_keepon_timeout(0);
+    // display_api->set_screen_set_keepon_timeout(5000);
+#endif
 }
diff --git a/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/RespiratoryTraining/RespiratoryTraining.bin b/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/RespiratoryTraining/RespiratoryTraining.bin
new file mode 100644 (file)
index 0000000..bc23fac
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c04df592f1983b48be8ea953fc16aeb299371367c2ef44b0526a8f0801124def
+size 38424
index 2688857..1bc5b75 100644 (file)
@@ -855,7 +855,8 @@ void ScreenAlwaysOnCtr(uint8_t turnOnFlag)
     const power_display_svr_api_t *display_api = power_display_svr_get_api();
     if(turnOnFlag)
     {
-        display_api->set_screen_set_keepon_timeout(0);
+        // display_api->set_screen_set_keepon_timeout(0);
+        
         if (display_api->get_screen_state() != SCREEN_ON)
         {
             display_api->turn_on_screen();