【切换表盘】UI
authorCaisking <Casiking@zhihuishixun.com>
Tue, 15 Apr 2025 07:01:38 +0000 (15:01 +0800)
committerCaisking <Casiking@zhihuishixun.com>
Tue, 15 Apr 2025 07:01:38 +0000 (15:01 +0800)
code/sdk/application/wearable/fd230/nativeapp/nativeui/set_dial/include/SetDialInfo.h
code/sdk/application/wearable/fd230/nativeapp/nativeui/set_dial/include/SetDialModel.h
code/sdk/application/wearable/fd230/nativeapp/nativeui/set_dial/include/SetDialModelC.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/set_dial/include/SetDialPresenter.h
code/sdk/application/wearable/fd230/nativeapp/nativeui/set_dial/include/SetDialView.h
code/sdk/application/wearable/fd230/nativeapp/nativeui/set_dial/src/SetDialModel.cpp
code/sdk/application/wearable/fd230/nativeapp/nativeui/set_dial/src/SetDialPresenter.cpp
code/sdk/application/wearable/fd230/nativeapp/nativeui/set_dial/src/SetDialView.cpp

index abc288d..158370c 100644 (file)
 #include <vector>\r
 #include <string>\r
 #include "common/image_cache_manager.h"\r
-namespace OHOS {\r
-    typedef struct {\r
-        uint8_t dialFlag; /* 1:离线表盘 0:预制表盘 */\r
-        uint8_t id;    /* 仅预制表盘使用 */\r
-        uint32_t resId;    /* 仅离线表盘使用 */\r
-        std::string dialFullName;  /* 仅离线表盘使用 */\r
-        std::string imageFullName; /* 仅预制表盘使用 */\r
-        std::string dialName;\r
-        std::string description;   /* 仅离线表盘使用 */\r
+namespace OHOS\r
+{\r
+    typedef struct\r
+    {\r
+        uint8_t dialFlag;          // 表盘标志 1:离线表盘 0:预制表盘\r
+        uint8_t id;                // 表盘Id 仅预制表盘使用\r
+        std::string dialFullName;  // 表盘路径 仅离线表盘使用\r
+        std::string imageFullName; // 表盘缩约图 仅预制表盘使用\r
+        std::string dialName;      // 表盘名\r
+        std::string description;   // 表盘描述 仅离线表盘使用\r
         ImageInfo *preImageInfo;\r
-        uint8_t capability;\r
     } SetDialInfo;\r
 }\r
 #endif
\ No newline at end of file
index ff3787b..9b37bc1 100644 (file)
-/*
- * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
- * Description: SetDialModel.h
- * Author:
- * Create: 2021-11-23
- */
 
 #ifndef SET_DIAL_MODEL_H
 #define SET_DIAL_MODEL_H
 #include "AppViewIDs.h"
-#include "UiConfig.h"
 #include "SetDialInfo.h"
 
-namespace OHOS {
-    class SetDialModel {
+namespace OHOS
+{
+    // 表盘类型
+    enum DIALTYPE
+    {
+        DEFULTDIAL,
+        DOWNLOADDIAL,
+    };
+    typedef struct DialLayout_
+    {
+        uint16_t dialId;
+        uint8_t batteryDisplay; // 电池配置 [0:无 1:白 2:黑]
+        uint8_t timeDisplay;    // 时间位置 [0:上 1:下]
+        uint8_t colorTypeSet;   // 颜色配置 [0:白 1:黑 2:灰 3:绿 4:橙 5:蓝]
+    }DialLayout;
+
+    // 定义特殊Id
+    constexpr uint16_t DEFAULT_DIAL_ID = 114;
+    constexpr uint16_t DEFAULT_DIAL_ID_0 = 1028;
+    constexpr uint16_t DEFAULT_DIAL_ID_1 = 111;
+    constexpr uint16_t DEFAULT_DIAL_ID_2 = 112;
+    constexpr uint16_t DEFAULT_DIAL_ID_3 = 113;
+    constexpr uint16_t MAX_DEFAULT_DIAL_ID = 115;
+    // 定义自定义表盘
+    constexpr uint16_t CUSTOM_DIAL_ID_1 = 1;
+    constexpr uint16_t CUSTOM_DIAL_ID_2 = 2;
+    constexpr uint16_t CUSTOM_DIAL_ID_3 = 3;
+    constexpr uint16_t CUSTOM_DIAL_ID_4 = 4;
+    constexpr uint16_t CUSTOM_DIAL_ID_5 = 5;
+    #define DIAL_ID_LENGTH 2
+    #define DIAL_NAME_LENGTH 50
+    #define DIAL_ID_PATH "user/userdata/dial_id.bin"
+
+    #define DIAL_MAX_NUM 10
+    #define DIAL_CUSTOM_MAX_NUM 1
+    #define DIAL_OFFLINE_DIAL_MAX_NUM 3
+    #define DIAL_RES_DIAL_MAX_NUM 5
+
+    
+    class SetDialModel
+    {
     public:
         static SetDialModel &GetInstance(void);
         void LoadAllDial(void);
         size_t GetDialCount(void);
-        std::vector<SetDialInfo>& GetDialInfo(void);
-        std::vector<SetDialInfo>& GetAmbientDialInfo(void);
-        void ClearDialInfo(void);
+        std::vector<SetDialInfo> &GetDialInfo(void);
         void SaveDialSetting(uint8_t pageIndex);
         uint8_t GetPageIndex(void);
+        void RegisterDial(uint16_t ID, const char *dialname);
+        uint16_t GetCurrentDialID();
+        bool IsDialInstalled(uint16_t ID);
+        bool UninstallDial(uint16_t ID);
+        void UpdateDialSetting(uint16_t ID);
+        uint16_t GetDialIdFromName(const std::string &dialName);
+        void PrintRegisteredDials(const std::unordered_map<uint16_t, std::string> &dials);
+        int GetAllDialIDs(char *allidStr,uint16_t MAX_LEN);
+
+
+        /*表盘map文件*/
+        bool readDialfile();
+        bool saveDialfile();
+        /*自定义表盘配置文件*/
+        bool saveDialConfig(const DialLayout &layout);
+        bool loadDialConfig(int Id, DialLayout &layout);
+        /*获取存储自定义表盘文件夹路径*/
+        std::string GetSaveDir(int Id);
+        /*【判断文件夹是否存在 不存在创建】*/
+        void CreateDirectoryIfNotExists(const std::string &path);
+        /*判断文件是否存在*/
+        bool CheckFileExists(const std::string &filePath);
+        /*通过表盘名*/
+        std::string GetDialDescription(const std::string &dialName);
+        /*获取自定义表盘名*/
+        std::string GetCustomName(int Id);
+        /*删除自定义表盘*/
+        bool DeleteCustomDial(uint16_t Id);
+        void TestDialConfig(void);
+        std::string GetSaveDir(int Id,uint8_t type);
+        void RegisterDial(uint16_t ID, const char *dialname, uint8_t type);
+
+        //判断是否可以继续下载表盘
+        bool CheckDialDownload(uint16_t ID,uint32_t dial_size);
+        void CheckDialSpace();
+
     private:
         void LoadAllDialFromRam(void);
         void LoadAllDialFromFs(void);
+        void LoadAllDialFromDefult(void);
         SetDialModel();
         SetDialModel(const SetDialModel &);
         SetDialModel &operator=(const SetDialModel &);
         virtual ~SetDialModel();
-        int32_t ParseDialHeader(const std::string &dialFileName, SetDialInfo &dialInfo);
+        int32_t ParseDialHeader(int type, const std::string &dialFileName, SetDialInfo &dialInfo);
         std::vector<SetDialInfo> dialInfoList;
-        std::vector<SetDialInfo> aodDialInfoList;
+        uint16_t currentDialID = 114; // 设置表盘默认值
+
+        uint16_t download_DialID = 1028;
+        uint32_t download_dialSize = 0;
+        bool downloadstate = false;
+        uint8_t downloadnum = 0;
     };
 }
 
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/set_dial/include/SetDialModelC.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/set_dial/include/SetDialModelC.h
new file mode 100644 (file)
index 0000000..bc6bf7b
--- /dev/null
@@ -0,0 +1,15 @@
+
+#ifndef SET_DIAL_MODEL_C_H
+#define SET_DIAL_MODEL_C_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void check_dial_space(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
index 80fc743..b65627a 100644 (file)
@@ -1,3 +1,9 @@
+/***
+ * @Date: 2024-07-05 11:09:20
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-08-03 15:12:30
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/set_dial/include/SetDialPresenter.h
+ */
 /*
  * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
  * Description: SetDialPresenter.h
 #include "KeyInputListener.h"
 #include "ModelListenerSample.h"
 
-namespace OHOS {
-
-const uint16_t MISS_DIAL_OPERATION_TIME = 3000;
-
-class SetDialView;
-class SetDialModel;
-class SetDialPresenter : public Presenter<SetDialView>,
-                         public UIView::OnClickListener, public ModelListenerSample,
-                         public UICoverflowView::OnCoverflowScrollListener,
-                         public UIRollerView::OnScrollListener {
-public:
-    SetDialPresenter();
-    ~SetDialPresenter() override;
-    size_t GetDialCount(void);
-    std::vector<SetDialInfo>& GetDialInfo(void);
-    uint8_t GetPageIndex(void);
-    void OnTickEvent() override;
-    void Notify() override {}
-    void OnStop() override;
-    bool OnScroll() override;
-    void OnScroll(UIRollerView* roller, std::string currentItemName, float currentItemAngle) override;
-    bool OnClick(UIView &view, const ClickEvent &event) override;
-    void ResetTickTimer(void);
-private:
-    void OnClickAction(void);
-    SetDialModel *model{nullptr};
-    uint64_t startTime{0};
-};
+namespace OHOS
+{
+
+    const uint16_t MISS_DIAL_OPERATION_TIME = 3000;
+
+    class SetDialView;
+    class SetDialModel;
+    class SetDialPresenter : public Presenter<SetDialView>,
+                             public UIView::OnClickListener,
+                             public ModelListenerSample,
+                             public UICoverflowView::OnCoverflowScrollListener,
+                             public UIRollerView::OnScrollListener,
+                             public RootView::OnKeyActListener
+    {
+    public:
+        SetDialPresenter();
+        ~SetDialPresenter() override;
+        size_t GetDialCount(void);
+        std::vector<SetDialInfo> &GetDialInfo(void);
+        uint8_t GetPageIndex(void);
+        void OnStart() override;
+        void OnResume() override;
+        void OnStop() override;
+        void OnTickEvent() override;
+        void Notify() override {}
+        bool OnScroll() override;
+        void OnScroll(UIRollerView *roller, std::string currentItemName, float currentItemAngle) override;
+        bool OnClick(UIView &view, const ClickEvent &event) override;
+
+        bool OnKeyAct(UIView &view, const KeyEvent &event) override; // 增加按键事件
+
+        void ResetTickTimer(void);
+
+    private:
+        void OnClickAction(void);
+        KeyInputListener *keyActListenr{nullptr};
+        SetDialModel *model{nullptr};
+        uint64_t startTime{0};
+    };
 }
 
 #endif // SET_DIAL_PRESENTER_H
\ No newline at end of file
index f26dc3b..e2de873 100644 (file)
@@ -1,3 +1,9 @@
+/*** 
+ * @Date: 2024-07-05 11:09:20
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-08-03 15:16:08
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/set_dial/include/SetDialView.h
+ */
 /*
  * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
  * Description: SetDialView.h
 #include "components/ui_view_group.h"
 #include "components/ui_coverflow_view.h"
 #include "components/ui_roller_view.h"
+#include "window/window.h"
+
 #include "ChangeSliceListener.h"
 #include "UiConfig.h"
+#include "KeyInputListener.h"
 
 namespace OHOS {
 static constexpr uint8_t DIVISOR_TWO = 2;
@@ -37,6 +46,7 @@ public:
     }
 
     void OnStart() override;
+    
     void CoverflowViewScroll(void);
     void RollerViewScroll(std::string currentItemName, float currentItemAngle);
     uint8_t GetCoverflowPage(void);
index 9e2c060..6271840 100644 (file)
-/*
- * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
- * Description: SetDialModel.cpp
- * Author:
- * Create: 2021-11-23
- */
-#include <algorithm>
+#include "set_dial/include/SetDialModel.h"
+#include "DialBinParser.h"
 #include "MainModel.h"
-#include "SetDialModel.h"
+#include "NativeAbility.h"
+#ifdef SUPPORT_BLE_SERVICE
+#include "bleEvent.h"
+#include "bletest.h"
+#endif
+#include "clock/include/MainClockView.h"
+#include "custom_runtime.h"
+#include "custom_utils.h"
+#include "dirent.h"
 #include "kv_store.h"
 #include "securec.h"
-#include "dirent.h"
-#include "DialBinParser.h"
+#include "set_dial/include/SetDialModelC.h"
+// #include "system/include/SystemLogModel.h"
 #include "wearable_log.h"
-
+#include <algorithm>
+#include <array>
+#include <cstdbool>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+#include <stdio.h>
+#include <string>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <unordered_set>
+extern "C" {
+void check_dial_space() { OHOS::SetDialModel::GetInstance().CheckDialSpace(); }
+}
 namespace OHOS {
-    SetDialModel::SetDialModel() {}
-
-    SetDialModel::~SetDialModel() {}
-
-    SetDialModel &SetDialModel::GetInstance()
-    {
-        static SetDialModel instance;
-        return instance;
-    }
-    void SetDialModel::LoadAllDial()
-    {
-        LoadAllDialFromRam(); // 导入在线表盘
-        size_t dialSize = dialInfoList.size();
-        size_t aodSize = aodDialInfoList.size();
-        LoadAllDialFromFs(); // 导入离线表盘
-        /* 只排序离线表盘 */
-        std::sort(dialInfoList.begin() + dialSize, dialInfoList.end(), [](const SetDialInfo& f, const SetDialInfo& n) {
-                    return f.dialName < n.dialName;
-                });
-        std::sort(aodDialInfoList.begin() + aodSize,
-            aodDialInfoList.end(),
-            [](const SetDialInfo &f, const SetDialInfo &n) { return f.dialName < n.dialName; });
-    }
-
-    void SetDialModel::LoadAllDialFromRam()
-    {
-        for (uint8_t i = 0; i < MainModel::GetInstance().GetDialInfoNum(); i++) {
-            const DialInfo *info = MainModel::GetInstance().GetDialInfo(i);
-            if (info != nullptr) {
-                SetDialInfo dialInfo{0};
-                dialInfo.dialFlag = 0;
-                dialInfo.id = i;
-                dialInfo.dialName = info->dialName;
-                dialInfo.imageFullName = info->dialImg;
-                ImageInfo* imageInfo = ImageCacheManager::GetInstance().LoadSingleRes(info->dialImg, false);
-                if (info == nullptr) {
-                    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "LoadAllDialFromRam loadimage %s fail",
-                                  info->dialImg);
-                    continue;
-                }
-                dialInfo.preImageInfo = imageInfo;
-                if (info->capability == DIAL_DISPLAY_CAPABILITY_NORMAL_ONLY) {
-                    dialInfoList.push_back(dialInfo);
-                } else if (info->capability == DIAL_DISPLAY_CAPABILITY_AMBITIENT_ONLY) {
-                    aodDialInfoList.push_back(dialInfo);
-                } else {
-                    dialInfoList.push_back(dialInfo);
-                    aodDialInfoList.push_back(dialInfo);
-                }
-            }
-        }
-    }
-
-    void SetDialModel::LoadAllDialFromFs()
-    {
-        int ret;
-        struct dirent *direntp;
-
-        // 打开目录
-        DIR *dirp = opendir(APP_DEFAULT_DIAL_PATH);
-        // 遍历文件
-        if (dirp != nullptr) {
-            while ((direntp = readdir(dirp)) != nullptr) {
-                SetDialInfo dialInfo{0};
-                int ret = ParseDialHeader(direntp->d_name, dialInfo);
-                if (ret == 0) {
-                    if (dialInfo.capability == DIAL_DISPLAY_CAPABILITY_NORMAL_ONLY) {
-                        dialInfoList.push_back(dialInfo);
-                    } else if (dialInfo.capability == DIAL_DISPLAY_CAPABILITY_AMBITIENT_ONLY) {
-                        aodDialInfoList.push_back(dialInfo);
-                    } else {
-                        dialInfoList.push_back(dialInfo);
-                        aodDialInfoList.push_back(dialInfo);
-                    }
-                }
-            }
-        }
-        // 关闭目录
-        closedir(dirp);
-        return;
-    }
-
-    int32_t SetDialModel::ParseDialHeader(const std::string &dialFileName, SetDialInfo &dialInfo)
-    {
-        std::string dialFullName = APP_DEFAULT_DIAL_PATH;
-        dialFullName += "/";
-        dialFullName += dialFileName;
-        FILE *fp = fopen(dialFullName.c_str(), "rb");
-        if (fp == nullptr) {
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ParseDialHeader cannot open file: %s",
-                          dialFullName.c_str());
-            return -1;
-        }
-        DialPreviewInfo preInfo{0};
-        bool ret = DialBinParserManager::GetInstance()->GetDialPreviewInfo(fp, &preInfo);
-        if (!ret) {
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "GetDialPreviewInfo %s fail",
-                          dialFullName.c_str());
-            fclose(fp);
-            return -1;
-        }
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ParseDialHeader dialFullName: %s",
-                      dialFullName.c_str());
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ParseDialHeader dialName: %s",
-                      preInfo.dialName);
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ParseDialHeader description: %s",
-                      preInfo.description);
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ParseDialHeader previewImgId: %u",
-                      preInfo.imgId);
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ParseDialHeader imageOffset: %u",
-                      preInfo.offset);
-        ImageInfo *info = ImageCacheManager::GetInstance().LoadOneInMultiRes(
-            preInfo.imgId, dialFullName, fp, false, preInfo.offset);
-        if (info == nullptr) {
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ParseDialHeader loadimage fail");
-            fclose(fp);
-            return -1;
-        }
-
-        dialInfo.dialFlag = 1;
-        dialInfo.id = 0;
-        dialInfo.resId = preInfo.imgId;
-        dialInfo.dialFullName = dialFullName;
-        dialInfo.dialName = preInfo.dialName;
-        dialInfo.description = preInfo.description;
-        dialInfo.preImageInfo = info;
-        dialInfo.capability = preInfo.capability;
-
-        fclose(fp);
-        return 0;
-    }
-
-    void SetDialModel::SaveDialSetting(uint8_t pageIndex)
-    {
-        if (pageIndex >= dialInfoList.size()) {
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDialModel SaveDialSetting [%u %u]",
-                          pageIndex, dialInfoList.size());
-            return;
-        }
+
+// 表盘map[Id--dialname] 前5个ID固定
+std::unordered_map<uint16_t, std::string> registeredDials{
+#ifdef CUSTOM_Z1
+    {DEFAULT_DIAL_ID_0, "Z1"},
+#else
+    {DEFAULT_DIAL_ID_0, "KUMI"},         // 为了预防显示
+    {DEFAULT_DIAL_ID, "obsidianrhythm"}, // 默认表盘修改为 黑耀律动
+#endif
+    {DEFAULT_DIAL_ID_1, "satellite"},       // 卫星表盘
+    {DEFAULT_DIAL_ID_2, "birdie"},          // 飞鸟表盘
+    {DEFAULT_DIAL_ID_3, "dawninsight"},     // 晨曦智影
+    {MAX_DEFAULT_DIAL_ID, "mirrorvoyager"}, // 镜影行者
+
+};
+// 表盘市场UID 对应表盘name
+// 存储表盘到文件
+bool SetDialModel::saveDialfile() {
+  FILE *fp = fopen(DIAL_ID_PATH, "wb");
+  if (!fp) {
+    WEARABLE_LOGE("File I/O", "Failed to open file for writing: %s",
+                  DIAL_ID_PATH);
+    return false;
+  }
+
+  for (const auto &entry : registeredDials) {
+    char buf[DIAL_ID_LENGTH + DIAL_NAME_LENGTH] = {0};
+    // 复制UID
+    memcpy_s(buf, DIAL_ID_LENGTH, &entry.first, DIAL_ID_LENGTH);
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RegisterDial %d %s is ok!", ID,
+                  "uid  %d", entry.first);
+
+    // 复制表盘名称,确保不越界
+    size_t name_length =
+        entry.second.copy(buf + DIAL_ID_LENGTH, DIAL_NAME_LENGTH - 1);
+    buf[DIAL_ID_LENGTH + name_length] = '\0'; // 确保字符串以null结尾
+
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RegisterDial %d %s is ok!", ID,
+                  "uid  %s", entry.second.c_str());
+
+    // 写入文件
+    size_t size =
+        fwrite(buf, sizeof(char), DIAL_ID_LENGTH + DIAL_NAME_LENGTH, fp);
+    if (size != (DIAL_ID_LENGTH + DIAL_NAME_LENGTH)) {
+      WEARABLE_LOGE("File I/O", "fwrite failed! Written bytes: %zu", size);
+      fclose(fp);
+      return false;
+    } else {
+      WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RegisterDial %d %s is ok!", ID,
+                    "fwrite succeeded for uid %d!", entry.first);
+    }
+  }
+  fclose(fp);
+  return true;
+}
+
+// 从文件读取表盘
+bool SetDialModel::readDialfile() {
+  FILE *fp = fopen(DIAL_ID_PATH, "rb");
+  if (!fp) {
+    WEARABLE_LOGE("File I/O", "Failed to open file for reading: %s",
+                  DIAL_ID_PATH);
+    return false;
+  }
+
+  fseek(fp, 0, SEEK_END);
+  long file_size = ftell(fp);
+  fseek(fp, 0, SEEK_SET);
+  WEARABLE_LOGD("Log", "readDialfile size is %ld!", file_size);
+
+  while (file_size > 0) {
+    uint16_t uid = 0;
+    if (fread(&uid, 1, DIAL_ID_LENGTH, fp) != DIAL_ID_LENGTH) {
+      WEARABLE_LOGE("File I/O", "fread failed for uid!");
+      break; // 读取出错,停止循环
+    }
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uid  %d", uid);
+    char name_buf[DIAL_NAME_LENGTH] = {0};
+    if (fread(name_buf, 1, DIAL_NAME_LENGTH, fp) != DIAL_NAME_LENGTH) {
+      WEARABLE_LOGE("File I/O", "fread failed for name_buf!");
+      break; // 读取出错,停止循环
+    }
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "name_buf %s", name_buf);
+    // 检查UID和名称的有效性
+    if (uid != 0 && name_buf[0] != '\0') {
+      if (!IsDialInstalled(uid)) {
+        RegisterDial(uid, name_buf);
+      }
+    } else {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "Invalid uid or empty name. uid: %d, name: %s", uid,
+                    name_buf);
+    }
+
+    file_size -= (DIAL_ID_LENGTH + DIAL_NAME_LENGTH);
+  }
+
+  fclose(fp);
+  return true;
+}
+
+SetDialModel::SetDialModel() {
+  LoadAllDial();     // 更新表盘个数 当前表盘
+  readDialfile();    // 读取表盘map配置文件
+  char idBuffer[10]; // 读取表盘Id配置文件
+  int len = UtilsGetValue("dial_id", idBuffer, sizeof(idBuffer));
+  if (len >= 0) {
+    currentDialID = std::stoi(idBuffer); // 将字符串转换为整数
+  }
+}
+
+SetDialModel::~SetDialModel() {}
+
+SetDialModel &SetDialModel::GetInstance() {
+  static SetDialModel instance;
+  return instance;
+}
+
+/* 注册表盘map */
+void SetDialModel::RegisterDial(uint16_t ID, const char *dialname) {
+
+  if (ID == 0 || strlen(dialname) == 0)
+    return;
+
+  registeredDials[ID] = std::string(dialname); // 唯一性
+
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RegisterDial %d %s is ok!", ID,
+                dialname);
+
+  // 手表加载map不需要遍历
+  // LoadAllDial();
+  // saveDialfile();
+}
+
+/* 注册表盘map_ble*/
+void SetDialModel::RegisterDial(uint16_t ID, const char *dialname,
+                                uint8_t type) {
+  // 增加 ID 对应
+  if (ID <= 4) {
+    ID++;
+  }
+
+  if (ID == 0 || strlen(dialname) == 0)
+    return;
+
+  registeredDials[ID] = std::string(dialname); // 唯一性
+
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RegisterDial %d %s is ok!", ID,
+                dialname);
+
+  LoadAllDial();
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " RegisterDial ble is ok!");
+
+  saveDialfile();
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " RegisterDial ble save is ok!");
+}
+
+/* 打印map */
+void SetDialModel::PrintRegisteredDials(
+    const std::unordered_map<uint16_t, std::string> &dials) {
+  printf("Registered Dials:\n");
+  for (const auto &entry : dials) {
+    printf("ID: %u | Name: %s\n", entry.first, entry.second.c_str());
+  }
+}
+
+/* 通过名字查询Id */
+uint16_t SetDialModel::GetDialIdFromName(const std::string &dialName) {
+  for (const auto &entry : registeredDials) {
+    if (entry.second == dialName) {
+      return entry.first; // 找到对应的表盘名称,返回对应ID
+    }
+  }
+  return 0; // 如果未找到对应的表盘名称,返回0或者其他适当的默认值
+}
+
+/* 获取当前表盘Id */
+uint16_t SetDialModel::GetCurrentDialID() {
+  if (registeredDials.find(currentDialID) != registeredDials.end()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "currentDialID is %d,name is %s",
+                  currentDialID, registeredDials[currentDialID].c_str());
+  }
+  uint16_t id = currentDialID;
+  if (currentDialID <= 5) {
+    id--;
+  }
+  return id;
+}
+/* 获取所有表盘Id 每个表盘Id 2个字节 拼接为字符串 */
+int SetDialModel::GetAllDialIDs(char *allidStr, uint16_t MAX_LEN) {
+  std::string allIDs;
+  int length = 0;
+  for (const auto &entry : registeredDials) {
+    uint16_t id = entry.first;
+    if (id <= 5) {
+      id--;
+    }
+    if (length < MAX_LEN)
+      memcpy_s(allidStr + length, 512, &id, 2);
+    length += 2;
+  }
+
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "allidStr is %s %d", allIDs.c_str(),
+                length);
+  return length;
+}
+/* 判断表盘是否存在*/
+bool SetDialModel::IsDialInstalled(uint16_t ID) {
+  if (ID <= 4) {
+    ID++;
+  }
+
+  if (registeredDials.find(ID) != registeredDials.end()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "dial %d is install!", ID);
+    return true;
+  } else {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "dial %d is not install!", ID);
+    return false;
+  }
+}
+/*删除自定义表盘*/
+bool SetDialModel::DeleteCustomDial(uint16_t Id) {
+  // 删除配置文件
+  std::string filename = GetSaveDir(Id) + "/" + std::to_string(Id) + ".bin";
+  if (!uapi_delete_files(filename.c_str())) {
+    WEARABLE_LOGE(
+        WEARABLE_LOG_MODULE_APP,
+        "DeleteCustomDial: Failed to delete the dial configuration file: %s",
+        filename.c_str());
+    return false;
+  }
+
+  // 删除资源文件
+  switch (Id) {
+  case CUSTOM_DIAL_ID_1:
+    if (!uapi_delete_files(CUSTOM_CLOCK1_DIALPER_PATH)) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "DeleteCustomDial: Failed to delete dial percentage file "
+                    "for ID 1: %s",
+                    CUSTOM_CLOCK1_DIALPER_PATH);
+      return false;
+    }
+    if (!uapi_delete_files(CUSTOM_CLOCK1_DIALBACK_PATH)) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "DeleteCustomDial: Failed to delete dial background file "
+                    "for ID 1: %s",
+                    CUSTOM_CLOCK1_DIALBACK_PATH);
+      return false;
+    }
+    break;
+
+  case CUSTOM_DIAL_ID_2:
+    if (!uapi_delete_files(CUSTOM_CLOCK2_DIALPER_PATH)) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "DeleteCustomDial: Failed to delete dial percentage file "
+                    "for ID 2: %s",
+                    CUSTOM_CLOCK2_DIALPER_PATH);
+      return false;
+    }
+    if (!uapi_delete_files(CUSTOM_CLOCK2_DIALBACK_PATH)) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "DeleteCustomDial: Failed to delete dial background file "
+                    "for ID 2: %s",
+                    CUSTOM_CLOCK2_DIALBACK_PATH);
+      return false;
+    }
+    break;
+
+  case CUSTOM_DIAL_ID_3:
+    if (!uapi_delete_files(CUSTOM_CLOCK3_DIALPER_PATH)) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "DeleteCustomDial: Failed to delete dial percentage file "
+                    "for ID 3: %s",
+                    CUSTOM_CLOCK3_DIALPER_PATH);
+      return false;
+    }
+    if (!uapi_delete_files(CUSTOM_CLOCK3_DIALBACK_PATH)) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "DeleteCustomDial: Failed to delete dial background file "
+                    "for ID 3: %s",
+                    CUSTOM_CLOCK3_DIALBACK_PATH);
+      return false;
+    }
+    break;
+
+  case CUSTOM_DIAL_ID_4:
+    if (!uapi_delete_files(CUSTOM_CLOCK4_DIALPER_PATH)) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "DeleteCustomDial: Failed to delete dial percentage file "
+                    "for ID 4: %s",
+                    CUSTOM_CLOCK4_DIALPER_PATH);
+      return false;
+    }
+    if (!uapi_delete_files(CUSTOM_CLOCK4_DIALBACK_PATH)) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "DeleteCustomDial: Failed to delete dial background file "
+                    "for ID 4: %s",
+                    CUSTOM_CLOCK4_DIALBACK_PATH);
+      return false;
+    }
+    break;
+
+  case CUSTOM_DIAL_ID_5:
+    if (!uapi_delete_files(CUSTOM_CLOCK5_DIALPER_PATH)) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "DeleteCustomDial: Failed to delete dial percentage file "
+                    "for ID 5: %s",
+                    CUSTOM_CLOCK5_DIALPER_PATH);
+      return false;
+    }
+    if (!uapi_delete_files(CUSTOM_CLOCK5_DIALBACK_PATH)) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "DeleteCustomDial: Failed to delete dial background file "
+                    "for ID 5: %s",
+                    CUSTOM_CLOCK5_DIALBACK_PATH);
+      return false;
+    }
+    break;
+
+  default:
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "DeleteCustomDial: Invalid dial ID: %d", Id);
+    return false; // ID 不合法
+  }
+
+  // 所有操作成功  重新加载list
+  registeredDials.erase(Id);
+  LoadAllDial();
+  WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP,
+                "DeleteCustomDial: Successfully deleted custom dial with ID %d",
+                Id);
+  //删除表盘,更新id文件
+  saveDialfile();
+  return true;
+}
+
+/* 删除表盘 */
+bool SetDialModel::UninstallDial(uint16_t ID) {
+  // 增加 ID 对应
+  if (ID <= 4) {
+    ID++;
+  }
+
+  if (registeredDials.find(ID) != registeredDials.end()) {
+    // 默认表盘不删除
+    switch (ID) {
+    case DEFAULT_DIAL_ID:
+    case MAX_DEFAULT_DIAL_ID:
+    case DEFAULT_DIAL_ID_0:
+    case DEFAULT_DIAL_ID_1:
+    case DEFAULT_DIAL_ID_2:
+    case DEFAULT_DIAL_ID_3:
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "UninstallDial: Default dial %d cannot be uninstalled", ID);
+      return false;
+
+    // 删除自定义表盘
+    case CUSTOM_DIAL_ID_1:
+    case CUSTOM_DIAL_ID_2:
+    case CUSTOM_DIAL_ID_3:
+    case CUSTOM_DIAL_ID_4:
+    case CUSTOM_DIAL_ID_5:
+      if (DeleteCustomDial(ID)) {
+        return true;
+      }
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "UninstallDial: Failed to uninstall custom dial %d", ID);
+      return false;
+    default:
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "UninstallDial: dial ID %d is offline dial", ID);
+      break;
+    }
+
+    // 删除文件操作
+    std::string dialFullName = APP_DOWNLOAD_DIAL_PATH;
+    dialFullName += "/";
+    dialFullName += registeredDials[ID];
+    dialFullName += ".bin";
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP,
+                  "UninstallDial: Attempting to delete %s",
+                  dialFullName.c_str());
+
+    if (uapi_delete_files(dialFullName.c_str())) {
+      WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP,
+                    "UninstallDial: Successfully deleted dial %d", ID);
+      registeredDials.erase(ID);
+      LoadAllDial();
+      return true;
+    }
+
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "UninstallDial: Failed to delete dial file %s",
+                  dialFullName.c_str());
+    return false;
+  }
+
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                "UninstallDial: Couldn't find the dial %d", ID);
+  return false;
+}
+/*更新表盘*/
+void SetDialModel::UpdateDialSetting(uint16_t ID) {
+  if (ID <= 4) {
+    ID++;
+  }
+
+  /*判断是否为当前表盘 如果是自定义表盘 需要更新*/
+  if (currentDialID == ID && ID >= 5) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "UpdateDialSetting: Current dial %d cannot be updated %d",
+                  currentDialID, ID);
+    // reply_app_send_switchDialCmd(false);
+    return;
+  }
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "UpdateDialSetting: ID %d", ID);
+  if (registeredDials.find(ID) != registeredDials.end()) {
+    std::string dialname = registeredDials[ID]; // 根据ID找到对应的表盘名称
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                  "UpdateDialSetting: Dial %s is already registered",
+                  dialname.c_str());
+    // 在dialInfoList中查找同名表盘
+    for (size_t i = 0; i < dialInfoList.size(); i++) {
+      WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                    "dialInfoList name %s is already registered",
+                    (dialInfoList[i].dialName).c_str());
+      if (dialInfoList[i].dialName == dialname) {
         DialSetting diagSetting;
-        SetDialInfo &info = dialInfoList[pageIndex];
+        SetDialInfo &info = dialInfoList[i];
         diagSetting.dialFlag = info.dialFlag;
         diagSetting.dialId = info.id;
         diagSetting.dialFullName = info.dialFullName;
-        MainModel::GetInstance().AddDialSetting(diagSetting);
+        currentDialID = ID;
+        uapi_set_screen_on_api(); // 更新当前表盘Id
+        MainModel::GetInstance().AddDialSetting(diagSetting,
+                                                currentDialID); // 更新表盘设置
+        //运动状态下不进行页面切换
+        // if (uapi_dev_runtime_get_train_status() != 1) {
+        //   NativeAbility::GetInstance().ChangeSlice(VIEW_MAIN);
+        // }
+        // svr_ble_read_data_value_updata_noyify(); // app切换表盘增加id更新
+        // reply_app_send_switchDialCmd(true);
+        return; // 更新成功后直接返回
+      }
     }
+    //没有在列表找到名称
+    // reply_app_send_switchDialCmd(false);
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                  "dialInfoList name %s is already registered",
+                  dialname.c_str());
+  } else {
+    // reply_app_send_switchDialCmd(false);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "SetDialModel UpdateDialSetting: Cannot find dial %d", ID);
+  }
+}
 
-    size_t SetDialModel::GetDialCount(void)
-    {
-        return dialInfoList.size();
+/*加载所有表盘*/
+void SetDialModel::LoadAllDial() {
+  dialInfoList.clear();
+  size_t dialSize = dialInfoList.size();
+  // 加载默认表盘
+  LoadAllDialFromDefult();
+  // 加载自定义表盘
+  LoadAllDialFromRam();
+  // 加载离线表盘
+  LoadAllDialFromFs();
+  /* 排序离线表盘
+  std::sort(dialInfoList.begin() + dialSize, dialInfoList.end(),
+            [](const SetDialInfo &f, const SetDialInfo &n) {
+              return f.dialName < n.dialName;
+            });
+  */
+  // 表盘Id以及表盘map打印
+  char dialId[128];
+  GetAllDialIDs(dialId, 128);
+  PrintRegisteredDials(registeredDials);
+}
+/*加载离线表盘*/
+void SetDialModel::LoadAllDialFromFs() {
+  int ret;
+  struct dirent *direntp;
+  downloadnum = 0; //记录离线表盘个数
+  // 打开目录
+  DIR *dirp = opendir(APP_DOWNLOAD_DIAL_PATH);
+  // 遍历文件
+  if (dirp != nullptr) {
+    while ((direntp = readdir(dirp)) != nullptr) {
+      SetDialInfo dialInfo{0};
+      int ret = ParseDialHeader(DOWNLOADDIAL, direntp->d_name, dialInfo);
+      if (ret == 0) {
+        dialInfoList.push_back(dialInfo);
+        downloadnum++;
+      }
     }
+  }
+  // 关闭目录
+  closedir(dirp);
+  return;
+}
+/*
+  加载默认表盘
+*/
+const std::vector<std::string> defaultDials = {
+    "obsidianrhythm", "mirrorvoyager", "satellite", "dawninsight", "birdie"};
+
+void SetDialModel::LoadAllDialFromDefult(void) {
+  DIR *dirp = opendir(APP_DEFAULT_DIAL_PATH);
+  if (dirp == nullptr) {
+    perror("Failed to open directory");
+    return;
+  }
 
-    std::vector<SetDialInfo>& SetDialModel::GetDialInfo(void)
-    {
-        return dialInfoList;
+  struct dirent *direntp;
+  std::unordered_set<std::string> availableDials;
+
+  // 收集可用的表盘名称
+  while ((direntp = readdir(dirp)) != nullptr) {
+    if (direntp->d_name[0] != '.') {
+      WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                    "LoadAllDialFromDefult: Found dial %s", direntp->d_name);
+      availableDials.insert(direntp->d_name);
     }
+  }
+
+  closedir(dirp);
 
-    std::vector<SetDialInfo>& SetDialModel::GetAmbientDialInfo(void)
-    {
-        return aodDialInfoList;
+  // 按照指定顺序加载表盘
+  for (const auto &dialName : defaultDials) {
+    std::string fullDialName = dialName + ".bin";
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Checking for dial: %s",
+                  fullDialName.c_str());
+
+    if (availableDials.count(fullDialName)) {
+      SetDialInfo dialInfo{0};
+      int ret = ParseDialHeader(DEFULTDIAL, fullDialName, dialInfo);
+      if (ret == 0) {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Adding dial %s",
+                      fullDialName.c_str());
+        dialInfoList.push_back(dialInfo);
+      } else {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                      "ParseDialHeader is error for file %s",
+                      fullDialName.c_str());
+      }
+    } else {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "LoadAllDialFromDefult: Cannot find dial %s",
+                    fullDialName.c_str()); // 记录找不到文件的详细信息
     }
+  }
+}
+/*通过表盘名称解析表盘 [离线表盘]*/
+int32_t SetDialModel::ParseDialHeader(int type, const std::string &dialFileName,
+                                      SetDialInfo &dialInfo) {
+  std::string dialFullName;
+  if (type == DEFULTDIAL) {
+    dialFullName = APP_DEFAULT_DIAL_PATH;
+  } else if (type == DOWNLOADDIAL) {
+    dialFullName = APP_DOWNLOAD_DIAL_PATH;
+  }
+  dialFullName += "/";
+  dialFullName += dialFileName;
+  FILE *fp = fopen(dialFullName.c_str(), "rb");
+  if (fp == nullptr) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "ParseDialHeader cannot open file: %s", dialFullName.c_str());
+    return -1;
+  }
+  DialPreviewInfo preInfo{0};
+  bool ret = DialBinParserManager::GetInstance()->GetDialPreviewInfo(fp, &preInfo);
+  if (!ret) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetDialPreviewInfo %s fail",
+                  dialFullName.c_str());
+    fclose(fp);
+    return -1;
+  }
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ParseDialHeader dialFullName: %s",
+                dialFullName.c_str());
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ParseDialHeader dialName: %s",
+                preInfo.dialName);
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ParseDialHeader description: %s",
+                preInfo.description);
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ParseDialHeader previewImgId: %u",
+                preInfo.imgId);
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ParseDialHeader imageOffset: %u",
+                preInfo.offset);
+  ImageInfo *info = ImageCacheManager::GetInstance().LoadOneInMultiRes(
+      preInfo.imgId, dialFullName, fp, false, preInfo.offset);
+  if (info == nullptr) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ParseDialHeader loadimage fail");
+    fclose(fp);
+    return -1;
+  }
+
+  dialInfo.dialFlag = 1;
+  dialInfo.id = 0;
+  dialInfo.dialFullName = dialFullName;
+  dialInfo.dialName = preInfo.dialName;
+  dialInfo.description = preInfo.description;
+  dialInfo.preImageInfo = info;
+
+  fclose(fp);
+  return 0;
+}
 
-    void SetDialModel::ClearDialInfo(void)
-    {
-        for (auto iter : dialInfoList) {
-            if (iter.dialFlag) {
-                ImageCacheManager::GetInstance().UnloadOneInMultiRes(iter.resId, iter.dialFullName);
-            } else {
-                ImageCacheManager::GetInstance().UnloadSingleRes(iter.imageFullName);
-            }
-        }
-        dialInfoList.clear();
+/*通过表盘名找到描述*/
+std::string SetDialModel::GetDialDescription(const std::string &dialName) {
+  for (size_t i = 0; i < dialInfoList.size(); i++) {
+    if (dialInfoList[i].dialName == dialName) {
+      //判断是否为离线表盘
+      if (dialInfoList[i].dialFlag)
+        return dialInfoList[i].description;
+      else
+        return dialInfoList[i].dialName;
     }
+  }
+  //未找到
+  return "";
+}
+
+/*设置当前表盘*/
+void SetDialModel::SaveDialSetting(uint8_t pageIndex) {
+  if (pageIndex >= dialInfoList.size()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "SetDialModel SaveDialSetting [%u %u]", pageIndex,
+                  dialInfoList.size());
+    return;
+  }
+  DialSetting diagSetting;
+  SetDialInfo &info = dialInfoList[pageIndex];
+  diagSetting.dialFlag = info.dialFlag;
+  diagSetting.dialId = info.id;
+  diagSetting.dialFullName = info.dialFullName;
+  currentDialID = GetDialIdFromName(info.dialName); // 更新表盘Id
 
-    uint8_t SetDialModel::GetPageIndex(void)
-    {
-        uint8_t index = 0;
-        DialSetting dialSetting = MainModel::GetInstance().GetDialSetting();
-        for (auto iter : dialInfoList) {
-            if (dialSetting.dialFlag) {
-                if (strcmp(iter.dialFullName.c_str(), dialSetting.dialFullName.c_str()) == 0) {
-                    return index;
-                }
-            } else {
-                if ((!iter.dialFlag) && (iter.id == dialSetting.dialId)) {
-                    return index;
-                }
-            }
-            index++;
-        }
-        return 0;
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "info.dialName %s info.id %d ",
+                info.dialName.c_str(), info.id);
+  MainModel::GetInstance().AddDialSetting(diagSetting, currentDialID);
+}
+
+/*获取表盘的总数*/
+size_t SetDialModel::GetDialCount(void) {
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " %d ", dialInfoList.size());
+  return dialInfoList.size();
+}
+
+/*获取表盘列表*/
+std::vector<SetDialInfo> &SetDialModel::GetDialInfo(void) {
+  return dialInfoList;
+}
+
+uint8_t SetDialModel::GetPageIndex(void) {
+  uint8_t index = 0;
+  DialSetting dialSetting = MainModel::GetInstance().GetDialSetting();
+  for (auto iter : dialInfoList) {
+    if (dialSetting.dialFlag) {
+      if (strcmp(iter.dialFullName.c_str(), dialSetting.dialFullName.c_str()) ==
+          0) {
+        return index;
+      }
+    } else {
+      if ((!iter.dialFlag) && (iter.id == dialSetting.dialId)) {
+        return index;
+      }
+    }
+    index++;
+  }
+  return 0;
+}
+/* --------------------------------- 自定义表盘配置
+ * -------------------------------- */
+/*加载自定义表盘*/
+void SetDialModel::LoadAllDialFromRam() {
+  for (uint8_t i = DIAL_CLOCK; i < DIAL_MAX; i++) {
+    // 获取表盘列表 读取自定义表盘配置
+    const DialInfo *info = MainModel::GetInstance().GetDialInfo((DialId)i);
+    if (info == nullptr) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "LoadAllDialFromRam: Dial info for ID %u is nullptr", i);
+      continue;
+    }
+
+    // 处理自定义配置文件
+    if (i != DIAL_CLOCK) {
+      std::string customFilePath =
+          GetSaveDir(i) + "/" + std::to_string(i) + ".bin";
+      if (!CheckFileExists(customFilePath)) {
+        WEARABLE_LOGE(
+            WEARABLE_LOG_MODULE_APP,
+            "Custom config file does not exist for ID: %u, filename: %s", i,
+            customFilePath.c_str());
+        continue;
+      }
+    }
+
+    // 初始化表盘信息
+    SetDialInfo dialInfo;
+    dialInfo.dialFlag = 0;
+    dialInfo.id = i;
+    dialInfo.dialName = info->dialName;
+    dialInfo.imageFullName = info->dialImg;
+
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Processing Dial ID %u: Name: %s", i,
+                  dialInfo.dialName.c_str());
+
+    // 加载图像资源 (因为自定义表盘可能更新。需要先对其进行卸载)
+    ImageCacheManager::GetInstance().UnloadSingleRes(info->dialImg);
+    ImageInfo *imageInfo =
+        ImageCacheManager::GetInstance().LoadSingleRes(info->dialImg, false);
+    if (imageInfo == nullptr) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "LoadAllDialFromRam load image %s failed", info->dialImg);
+      continue;
     }
 
+    // 设置图像信息
+    dialInfo.preImageInfo = imageInfo;
+
+    // 添加到表盘列表
+    dialInfoList.push_back(dialInfo);
+
+    // 注册到map
+    // RegisterDial(dialInfo.id, dialInfo.dialName.c_str());
+
+    // 日志输出
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "Parsed Dial: ID: %u, Name: %s, Image: %s", dialInfo.id,
+                  dialInfo.dialName.c_str(), dialInfo.imageFullName.c_str());
+  }
+}
+
+// 检查文件是否存在的辅助函数
+bool SetDialModel::CheckFileExists(const std::string &filePath) {
+  std::ifstream file(filePath);
+  return file.is_open();
 }
+// 测试表盘配置写文件
+void SetDialModel::TestDialConfig() {
+  DialLayout dialconfig;
+
+  /*设置表盘参数*/
+  dialconfig.dialId = 1;
+  dialconfig.batteryDisplay = 1;
+  dialconfig.timeDisplay = 0;
+  dialconfig.colorTypeSet = 5;
+
+  if (!saveDialConfig(dialconfig)) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to save dial config");
+  }
+}
+// 保存自定义表盘配置到文件
+bool SetDialModel::saveDialConfig(const DialLayout &layout) {
+
+  std::string filename =
+      GetSaveDir(layout.dialId) + "/" + std::to_string(layout.dialId) + ".bin";
+
+  // 创建或打开文件
+  std::ofstream configFile(filename,
+                           std::ios::binary | std::ios::out | std::ios::trunc);
+  if (!configFile.is_open()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "Unable to open config file for writing: %s",
+                  filename.c_str());
+    return false; // 文件打开失败
+  }
+
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "saveDialConfig: %d %d %d",
+                layout.batteryDisplay, layout.timeDisplay, layout.colorTypeSet);
+
+  // 将结构体的三个数据按1个字节的存储到文件
+  configFile.put(
+      static_cast<char>(layout.batteryDisplay)); // 第一字节:电池图标样式
+  configFile.put(
+      static_cast<char>(layout.timeDisplay)); // 第二字节:时间label位置
+  configFile.put(static_cast<char>(layout.colorTypeSet)); // 第三字节:字体颜色
+
+  // 关闭文件
+  configFile.close();
+  return true; // 成功写入配置
+}
+
+/*
+    从配置文件读取设置
+    配置文件名:表盘ID
+    第一个字节:电池图标样式
+    第二个字节:时间label位置
+    第三个字节:字体颜色
+*/
+bool SetDialModel::loadDialConfig(int Id, DialLayout &layout) {
+  std::string filename = GetSaveDir(Id) + "/" + std::to_string(Id) + ".bin";
+  // 打开文件
+  std::ifstream configFile(filename, std::ios::binary);
+  if (!configFile.is_open()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "Unable to open config file for reading: %s",
+                  filename.c_str());
+    return false; // 文件打开失败
+  }
+
+  // 读取配置
+  std::array<char, 3> settings;
+  configFile.read(settings.data(), settings.size());
+
+  if (configFile.gcount() != settings.size()) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to read configuration: %s",
+                  filename.c_str());
+    return false; // 读取失败
+  }
+
+  // 为成员变量赋值
+  layout.batteryDisplay =
+      static_cast<BatteryDisplayType>(settings[0]); // 电池图标样式
+  layout.timeDisplay =
+      static_cast<TimeDisplayPosition>(settings[1]); // 时间label位置
+  layout.colorTypeSet = static_cast<ColorTypeSet>(settings[2]); // 字体颜色
+
+  // 关闭文件
+  configFile.close();
+  return true; // 成功读取配置
+}
+
+/*创建文件夹*/
+void SetDialModel::CreateDirectoryIfNotExists(const std::string &path) {
+  struct stat info;
+  if (stat(path.c_str(), &info) != 0) {
+    if (mkdir(path.c_str(), 0755) != 0) {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "Error: Could not create directory %s. Errno: %d",
+                    path.c_str(), errno);
+    } else {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Created directory: %s",
+                    path.c_str());
+    }
+  } else if (info.st_mode & S_IFDIR) {
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Directory already exists: %s",
+                  path.c_str());
+  }
+}
+
+/*
+    获取存储文件夹
+    Id(0~4)通过ID返回对应的文件夹路径
+    0 {已经被用}
+    1
+    2
+    3
+    4
+*/
+std::string SetDialModel::GetSaveDir(int Id) {
+  // 首先检查Id是否在0~5的范围内
+  if (Id <= 0 || Id > 5) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "Error: Id must be between 1 and 4.");
+    return ""; // 或者返回一个空字符串
+  }
+  // 检查 APP_CUSTOM_DIAL_PATH 是否存在
+  CreateDirectoryIfNotExists(APP_CUSTOM_DIAL_PATH);
+
+  std::string folderPath =
+      std::string(APP_CUSTOM_DIAL_PATH) + "/" + std::to_string(Id);
+  CreateDirectoryIfNotExists(folderPath); // 确保目录存在
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Directory is %s", folderPath.c_str());
+
+  return folderPath; // 返回目录路径
+}
+
+std::string SetDialModel::GetSaveDir(int Id, uint8_t type) {
+  // 首先检查Id是否在0~4的范围内
+  if (Id <= 4) {
+    Id++;
+  }
+
+  if (Id <= 0 || Id > 4) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "Error: Id must be between 1 and 4.");
+    return ""; // 或者返回一个空字符串
+  }
+  // 检查 APP_CUSTOM_DIAL_PATH 是否存在
+  CreateDirectoryIfNotExists(APP_CUSTOM_DIAL_PATH);
+
+  std::string folderPath =
+      std::string(APP_CUSTOM_DIAL_PATH) + "/" + std::to_string(Id);
+  CreateDirectoryIfNotExists(folderPath); // 确保目录存在
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Directory is %s", folderPath.c_str());
+
+  return folderPath; // 返回目录路径
+}
+
+/*获取自定义表盘名*/
+std::string SetDialModel::GetCustomName(int Id) {
+  // 首先检查Id是否在0~4的范围内
+  if (Id <= 4) {
+    Id++;
+  }
+
+  if (Id <= 0 || Id > 4) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "Error: Id must be between 1 and 4.");
+    return ""; // 或者返回一个空字符串
+  }
+
+  // 获取表盘列表 读取自定义表盘配置
+  const DialInfo *info = MainModel::GetInstance().GetDialInfo((DialId)Id);
+
+  if (info == nullptr) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "LoadAllDialFromRam: Dial info for ID %u is nullptr", Id);
+    return "";
+  }
+
+  return (info->dialName);
+}
+
+//判断是否可以继续下载表盘
+void SetDialModel::CheckDialSpace() {
+  // downloadstate = true;
+  // //安装离线表盘
+  // if (download_DialID > 5) {
+  //   //离线表盘 判断当前离线表盘个数
+  //   uint8_t offlinedial_num =
+  //       DIAL_OFFLINE_DIAL_MAX_NUM - downloadnum; //最多下载3个
+  //   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+  //                 "CheckDialSpace: Offline dial count %d", offlinedial_num);
+  //   if (offlinedial_num <= 0) {
+  //     //离线表盘个数已到上限
+  //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+  //                   "CheckDialSpace: Offline dial count %d", offlinedial_num);
+  //     downloadstate = false;
+  //     return;
+  //   } else {
+  //     //判断offlinedial文件夹内存是否可以继续存储
+  //     downloadstate = SystemLogModel::GetInstance()->canSyncFile(
+  //         TOTAL_DIAL_SPACE_PATH, TOTAL_DIAL_SPACE, download_dialSize);
+  //     //离线表盘
+  //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CheckDialSpace: Offline dial %d",
+  //                   downloadstate);
+  //     return;
+  //   }
+  // } else {
+  //   //安装自定义表盘
+  //   downloadstate = SystemLogModel::GetInstance()->canSyncFile(
+  //       TOTAL_CUSTOM_DAIL_SPACE_PATH, TOTAL_CUSTOM_DAIL_SPACE,
+  //       download_dialSize);
+  //   //自定义表盘
+  //   WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CheckDialSpace: Custom dial %d",
+  //                 downloadstate);
+  // }
+}
+
+bool SetDialModel::CheckDialDownload(uint16_t ID, uint32_t dial_size) {
+
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CheckDialDownload: %d %d", ID,
+                dial_size);
+
+  download_DialID = ID;
+  download_dialSize = dial_size;
+
+  // do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CHECK_DIAL_SPACE,
+  // nullptr,0);
+  CheckDialSpace();
+
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CheckDialDownload: %d",
+                downloadstate);
+  return downloadstate;
+}
+
+} // namespace OHOS
index 2f43932..ed7347e 100644 (file)
@@ -1,3 +1,9 @@
+/***
+ * @Date: 2024-07-05 11:09:20
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-08-03 15:11:43
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/set_dial/src/SetDialPresenter.cpp
+ */
 /*
  * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
  * Description: SetDialPresenter.cpp
 #include "SetDialView.h"
 #include "SetDialModel.h"
 #include "SetDialPresenter.h"
-#include "hal_tick.h"
-#include "NativeRegisterManager.h"
-
-
-namespace OHOS {
-
-REGIST_SLICE(VIEW_SET_DIAL, SetDialView, SetDialPresenter);
 
+#include "KeyInputListener.h"
+#include "custom_utils.h"
+#include "common/key_code.h"
+#ifdef SUPPORT_BLE_SERVICE
+#include "bleEvent.h"
+#include "bletest.h"
+#endif
+namespace OHOS
+{
     SetDialPresenter::SetDialPresenter()
     {
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDialPresenter::SetDialPresenter");
@@ -24,7 +32,18 @@ REGIST_SLICE(VIEW_SET_DIAL, SetDialView, SetDialPresenter);
         ResetTickTimer();
     }
 
-    SetDialPresenter::~SetDialPresenter()
+    SetDialPresenter::~SetDialPresenter() {}
+
+    void SetDialPresenter::OnStart()
+    {
+        Presenter<SetDialView>::OnStart();
+    }
+
+    void SetDialPresenter::OnResume(void)
+    {
+    }
+
+    void SetDialPresenter::OnStop(void)
     {
     }
 
@@ -32,13 +51,20 @@ REGIST_SLICE(VIEW_SET_DIAL, SetDialView, SetDialPresenter);
     {
         uint8_t pageIndex = view_->GetCoverflowPage();
         model->SaveDialSetting(pageIndex);
+        /*切换当前表盘*/
         NativeAbility::GetInstance().ChangeSlice(VIEW_MAIN);
+        NativeAbility::GetInstance().ClearSliceIdStack(); // 清空Slice栈
     }
 
     bool SetDialPresenter::OnClick(UIView &view, const ClickEvent &event)
     {
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDialPresenter::OnClick");
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetDialPresenter::OnClick");
         OnClickAction();
+
+        //具有延迟 更新表盘
+        // svr_ble_read_data_value_updata_noyify();
+        // Watch_SendDial_ToAppCmd();
+
         return true;
     }
 
@@ -48,7 +74,7 @@ REGIST_SLICE(VIEW_SET_DIAL, SetDialView, SetDialPresenter);
         return true;
     }
 
-    void SetDialPresenter::OnScroll(UIRollerView* roller, std::string currentItemName, float currentItemAngle)
+    void SetDialPresenter::OnScroll(UIRollerView *roller, std::string currentItemName, float currentItemAngle)
     {
         view_->RollerViewScroll(currentItemName, currentItemAngle);
     }
@@ -58,7 +84,7 @@ REGIST_SLICE(VIEW_SET_DIAL, SetDialView, SetDialPresenter);
         return model->GetDialCount();
     }
 
-    std::vector<SetDialInfo>& SetDialPresenter::GetDialInfo(void)
+    std::vector<SetDialInfo> &SetDialPresenter::GetDialInfo(void)
     {
         return model->GetDialInfo();
     }
@@ -70,19 +96,31 @@ REGIST_SLICE(VIEW_SET_DIAL, SetDialView, SetDialPresenter);
 
     void SetDialPresenter::OnTickEvent()
     {
-        uint64_t current_time = static_cast<uint64_t>(HALTick::GetInstance().GetTime());
+        // 屏蔽自动设置表盘
+#if 0
+        uint64_t current_time = osKernelGetTick2ms();
         if ((startTime != 0) && (current_time - startTime > MISS_DIAL_OPERATION_TIME)) {
             OnClickAction();
         }
+#endif
     }
 
-    void SetDialPresenter::OnStop()
+    void SetDialPresenter::ResetTickTimer(void)
     {
-        model->ClearDialInfo();
+        // startTime = osKernelGetTick2ms();
     }
 
-    void SetDialPresenter::ResetTickTimer(void)
+    // 增加按键事件
+    bool SetDialPresenter::OnKeyAct(UIView &view, const KeyEvent &event)
     {
-        startTime = static_cast<uint64_t>(HALTick::GetInstance().GetTime());
+        unsigned short keyID = event.GetKeyId();
+        unsigned short keyState = event.GetState();
+        // 如果是power键,且是亮屏状态,按键释放就返回上一级
+        if (keyID == static_cast<uint16_t>(ZliteKeyCode::ZLITE_KEY_POWER) && keyState == 1 && uapi_get_screen_state() == 0)
+        {
+            // 回退
+            NativeAbility::GetInstance().Back();
+        }
+        return true;
     }
 }
index 15bba5f..94edacf 100644 (file)
 #include "SetDialPresenter.h"
 #include "SetDialStyleModel.h"
 
-namespace OHOS {
-SetDialView::SetDialView()
+namespace OHOS
 {
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDialView::SetDialView");
-}
-
-SetDialView::~SetDialView()
-{
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDialView::~SetDialView");
-}
+    SetDialView::SetDialView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDialView::SetDialView");
+    }
 
-void SetDialView::OnStart()
-{
-    if (SetDialStyleModel::GetInstance().GetStyle() == DialStyle::COVERFLOW) {
-        SetUpCoverflowView();
-    } else {
-        SetUpRollerView();
+    SetDialView::~SetDialView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDialView::~SetDialView");
     }
-}
 
-void SetDialView::SetUpCoverflowView(void)
-{
-    coverflow_.SetPosition(0, 0, GetRootContainer()->GetWidth(), GetRootContainer()->GetHeight());
-    coverflow_.SetIntercept(true);
-    coverflow_.SetOnCoverflowListener(presenter_);
-    coverflow_.SetOnClickListener(presenter_);
-    coverflow_.SetThrowDrag(true);
-    std::vector<SetDialInfo> &dialInfo = presenter_->GetDialInfo();
-    for (auto iter : dialInfo) {
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDialView::SetUpCoverflowView %s",
-                      iter.dialName.c_str());
-        coverflow_.Add(iter.dialName.c_str(), iter.preImageInfo);
+    void SetDialView::OnStart()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDialView::OnStart");
+       
+        if (SetDialStyleModel::GetInstance().GetStyle() == DialStyle::COVERFLOW)
+        {
+            SetUpCoverflowView();
+        }
+        else
+        {
+            SetUpRollerView();
+        }
+
+        RootView::GetInstance()->SetOnKeyActListener(presenter_);
     }
-    lastIndex_ = presenter_->GetPageIndex();
-    coverflow_.SetCurrentPage(lastIndex_);
 
-    label_.SetPosition(127, 50, 200, 50);
-    label_.SetTextColor(Color::White());
-    label_.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
-    label_.SetText(dialInfo[lastIndex_].dialName.c_str());
-    label_.SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+    void SetDialView::SetUpCoverflowView(void)
+    {
+        coverflow_.SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
+        coverflow_.SetIntercept(true);
+        coverflow_.SetOnCoverflowListener(presenter_);
+        coverflow_.SetOnClickListener(presenter_);
+        coverflow_.SetThrowDrag(true);
+        std::vector<SetDialInfo> &dialInfo = presenter_->GetDialInfo();
+        for (auto iter : dialInfo)
+        {
 
-    AddViewToRootContainer(&coverflow_);
-    AddViewToRootContainer(&label_);
-}
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDialView::SetUpCoverflowView  dialName %s",
+                          iter.dialName.c_str());
+            coverflow_.Add(iter.dialName.c_str(), iter.preImageInfo);
+        }
+        lastIndex_ = presenter_->GetPageIndex();
+        coverflow_.SetCurrentPage(lastIndex_);
 
-void SetDialView::SetUpRollerView(void)
-{
-    rollerView_.SetPosition(0, 0, GetRootContainer()->GetWidth(), GetRootContainer()->GetHeight());
-    rollerView_.SetItemSize(150, 150); // 150: item size
-    rollerView_.SetThrowDrag(true);
-    rollerView_.SetItemPadding(80); // 80: item padding
-    AddViewToRootContainer(&rollerView_);
-
-    std::vector<SetDialInfo> &dialInfo = presenter_->GetDialInfo();
-    for (auto iter : dialInfo) {
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDialView::SetUpRollerView %s",
-                      iter.dialName.c_str());
-        bool succ = rollerView_.AddItem(iter.dialName, iter.preImageInfo);
-        rollerItemNum_ += succ ? 1 : 0;
-    }
-    float scalerCoef = 0.55;
-    uint16_t w = GetRootContainer()->GetWidth();
-    uint16_t h = GetRootContainer()->GetHeight();
-    rollerView_.SetItemSize(w * scalerCoef, h * scalerCoef);
-    lastIndex_ = presenter_->GetPageIndex();
-    rollerView_.SetCurrentItem(dialInfo[lastIndex_].dialName);
-    rollerView_.SetOnClickListener(presenter_);
-    rollerView_.SetOnScrollListener(presenter_);
-
-    label_.SetPosition(127, 50, 200, 50);
-    label_.SetTextColor(Color::White());
-    label_.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
-    label_.SetText(dialInfo[lastIndex_].dialName.c_str());
-    label_.SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
-    AddViewToRootContainer(&label_);
-}
+        label_.SetPosition(127, 50, 200, 50);
+        label_.SetTextColor(Color::White());
+        label_.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
 
-void SetDialView::CoverflowViewScroll(void)
-{
-    int16_t contMidX = static_cast<int16_t>(GetRootContainer()->GetWidth() / DIVISOR_TWO);
-    int16_t minOffset = contMidX;
-    uint8_t newCenterIndex = lastIndex_;
-    for (uint8_t i = 0; i < coverflow_.GetChildrenNumber(); i++) {
-        Rect rect =  coverflow_.GetViewByIndex(i)->GetOrigRect();
-        int16_t x = rect.GetLeft();
-        int16_t x1 = rect.GetRight();
-        int16_t xMid = static_cast<int16_t>(x + (x1 - x + 1) / DIVISOR_TWO);
-        int16_t distance = MATH_ABS(xMid - contMidX);
-        if (distance < minOffset) {
-            newCenterIndex = i;
-            minOffset = distance;
+        if (dialInfo[lastIndex_].dialFlag)
+        {
+            // 切换表盘[表盘名称设置{多国语言需要配置xml里面的表盘描述}]
+            label_.SetText(dialInfo[lastIndex_].description.c_str());
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetText dialName %s",
+                          dialInfo[lastIndex_].description.c_str());
         }
+        else
+        {
+            label_.SetText(dialInfo[lastIndex_].dialName.c_str());
+        }
+
+        label_.SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+
+        // 增加表冠控制
+        coverflow_.SetRotateFactor(2);
+        coverflow_.RequestFocus();
+
+        AddViewToRootContainer(&coverflow_);
+        
+        label_.SetVisible(false); 
+        AddViewToRootContainer(&label_);
     }
-    if (newCenterIndex != lastIndex_) {
-        lastIndex_ = newCenterIndex;
+
+    void SetDialView::SetUpRollerView(void)
+    {
+        rollerView_.SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
+        rollerView_.SetItemSize(150, 150); // 150: item size
+        rollerView_.SetThrowDrag(true);
+        rollerView_.SetItemPadding(80); // 80: item padding
+
+        AddViewToRootContainer(&rollerView_);
+
         std::vector<SetDialInfo> &dialInfo = presenter_->GetDialInfo();
+        for (auto iter : dialInfo)
+        {
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetDialView::SetUpRollerView %s",
+                          iter.dialName.c_str());
+            bool succ = rollerView_.AddItem(iter.dialName, iter.preImageInfo);
+            rollerItemNum_ += succ ? 1 : 0;
+        }
+        float scalerCoef = 0.55;
+        uint16_t w = Screen::GetInstance().GetWidth();
+        uint16_t h = Screen::GetInstance().GetHeight();
+        rollerView_.SetItemSize(w * scalerCoef, h * scalerCoef);
+        lastIndex_ = presenter_->GetPageIndex();
+        rollerView_.SetCurrentItem(dialInfo[lastIndex_].dialName);
+        rollerView_.SetOnClickListener(presenter_);
+        rollerView_.SetOnScrollListener(presenter_);
+
+        // 增加表冠控制
+        rollerView_.SetRotateFactor(2);
+        rollerView_.RequestFocus();
+
+        label_.SetPosition(127, 50, 200, 50);
+        label_.SetTextColor(Color::White());
+        label_.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
         label_.SetText(dialInfo[lastIndex_].dialName.c_str());
+        label_.SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+        //屏蔽
+        label_.SetVisible(false); 
+        AddViewToRootContainer(&label_);
     }
+   
 
-    Rect curViewRect = coverflow_.GetViewByIndex(lastIndex_)->GetOrigRect();
-    int16_t centerMid = curViewRect.GetLeft() + curViewRect.GetWidth() / DIVISOR_TWO;
-    int16_t offset = MATH_ABS(contMidX - centerMid);
-    if (offset > curViewRect.GetWidth() / DIVISOR_TWO) {
-        label_.SetStyle(STYLE_TEXT_OPA, 0);
-    } else {
-        uint8_t alpha =  (uint8_t)((1.0f - ((float)offset / (curViewRect.GetWidth() / DIVISOR_TWO))) * OPA_OPAQUE);
-        label_.SetStyle(STYLE_TEXT_OPA, alpha);
-    }
-    presenter_->ResetTickTimer();
-}
+    void SetDialView::CoverflowViewScroll(void)
+    {
+        int16_t contMidX = static_cast<int16_t>(Screen::GetInstance().GetWidth() / DIVISOR_TWO);
+        int16_t minOffset = contMidX;
+        uint8_t newCenterIndex = lastIndex_;
+        for (uint8_t i = 0; i < coverflow_.GetChildrenNumber(); i++)
+        {
+            Rect rect = coverflow_.GetViewByIndex(i)->GetOrigRect();
+            int16_t x = rect.GetLeft();
+            int16_t x1 = rect.GetRight();
+            int16_t xMid = static_cast<int16_t>(x + (x1 - x + 1) / DIVISOR_TWO);
+            int16_t distance = MATH_ABS(xMid - contMidX);
+            if (distance < minOffset)
+            {
+                newCenterIndex = i;
+                minOffset = distance;
+            }
+        }
+        if (newCenterIndex != lastIndex_)
+        {
+            lastIndex_ = newCenterIndex;
+            std::vector<SetDialInfo> &dialInfo = presenter_->GetDialInfo();
+            if (dialInfo[lastIndex_].dialFlag)
+            {
+                // 切换表盘[表盘名称设置{多国语言需要配置xml里面的表盘描述}]
+                label_.SetText(dialInfo[lastIndex_].description.c_str());
+                WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetText dialName %s",
+                              dialInfo[lastIndex_].description.c_str());
+            }
+            else
+            {
+                label_.SetText(dialInfo[lastIndex_].dialName.c_str());
+            }
+        }
 
-void SetDialView::RollerViewScroll(std::string currentItemName, float currentItemAngle)
-{
-    const float baseAngle = 360.0;
-    const float halfBaseAngle = 180.0;
-    if (FloatMoreEqual(currentItemAngle, halfBaseAngle)) {
-        currentItemAngle -= baseAngle;
-    }
-    if (currentItemAngle < 0) {
-        currentItemAngle = -currentItemAngle;
+        Rect curViewRect = coverflow_.GetViewByIndex(lastIndex_)->GetOrigRect();
+        int16_t centerMid = curViewRect.GetLeft() + curViewRect.GetWidth() / DIVISOR_TWO;
+        int16_t offset = MATH_ABS(contMidX - centerMid);
+        if (offset > curViewRect.GetWidth() / DIVISOR_TWO)
+        {
+            label_.SetStyle(STYLE_TEXT_OPA, 0);
+        }
+        else
+        {
+            uint8_t alpha = (uint8_t)((1.0f - ((float)offset / (curViewRect.GetWidth() / DIVISOR_TWO))) * OPA_OPAQUE);
+            label_.SetStyle(STYLE_TEXT_OPA, alpha);
+        }
+        presenter_->ResetTickTimer();
     }
-    float maxAngle = baseAngle / rollerItemNum_;
-    float coef = 1.0 - 1.0 / (maxAngle) * currentItemAngle;
-    label_.SetStyle(STYLE_TEXT_OPA, coef * OPA_OPAQUE);
-    label_.SetText(currentItemName.c_str());
-    std::vector<SetDialInfo> &dialInfo = presenter_->GetDialInfo();
-    for (uint8_t i = 0; i < dialInfo.size(); ++i) {
-        if (dialInfo[i].dialName == currentItemName) {
-            lastIndex_ = i;
+
+    void SetDialView::RollerViewScroll(std::string currentItemName, float currentItemAngle)
+    {
+        const float baseAngle = 360.0;
+        const float halfBaseAngle = 180.0;
+        if (FloatMoreEqual(currentItemAngle, halfBaseAngle))
+        {
+            currentItemAngle -= baseAngle;
+        }
+        if (currentItemAngle < 0)
+        {
+            currentItemAngle = -currentItemAngle;
+        }
+        float maxAngle = baseAngle / rollerItemNum_;
+        float coef = 1.0 - 1.0 / (maxAngle)*currentItemAngle;
+        label_.SetStyle(STYLE_TEXT_OPA, coef * OPA_OPAQUE);
+        // label_.SetText(currentItemName.c_str());
+        std ::string dialnamestr = SetDialModel::GetInstance().GetDialDescription(currentItemName);
+        // printf("currentItemName %s\n", dialnamestr.c_str());
+        label_.SetText(dialnamestr.c_str());
+        std::vector<SetDialInfo> &dialInfo = presenter_->GetDialInfo();
+        for (uint8_t i = 0; i < dialInfo.size(); ++i)
+        {
+            if (dialInfo[i].dialName == currentItemName)
+            {
+                lastIndex_ = i;
+            }
         }
+        presenter_->ResetTickTimer();
+    }
+
+    uint8_t SetDialView::GetCoverflowPage(void)
+    {
+        return lastIndex_;
     }
-    presenter_->ResetTickTimer();
-}
 
-uint8_t SetDialView::GetCoverflowPage(void)
-{
-    return lastIndex_;
-}
 }