增加自定义表盘的内容移植 2212/3 2212/head 2214/target/1 2215/target/1
authorCaisking <Casiking@zhihuishixun.com>
Tue, 9 Sep 2025 03:32:07 +0000 (11:32 +0800)
committerCaisking <Casiking@zhihuishixun.com>
Tue, 9 Sep 2025 03:32:07 +0000 (11:32 +0800)
code/sdk/application/wearable/fd230/nativeapp/nativeui/clock/include/MainClockView.h
code/sdk/application/wearable/fd230/nativeapp/nativeui/clock/src/MainClockView.cpp
code/sdk/zhihui/services/ble_service/bleservice/bleEvent.c

index 13b254a..732cce4 100644 (file)
@@ -14,8 +14,8 @@
  #ifndef MAIN_CLOCK_VIEW_H
  #define MAIN_CLOCK_VIEW_H
  
+ #include <cstdint>
  #include <string>
- #include <time.h>
  #include "View.h"
  #include "components/ui_view_group.h"
  #include "components/ui_image_view.h"
@@ -38,6 +38,9 @@
  #include "animator/animator_manager.h"
  #include "time.h"
  #include "sys/time.h"
+ #include "components/ui_lite_surface_view.h"
+ #include "video_play_wrapper.h"
+ #include "main/include/dial/DialVideoView.h"
  
  namespace OHOS
  {
@@ -68,7 +71,7 @@
          TIME_DISPLAY_DEFAULT = TIME_DISPLAY_BELOW // 默认:下方
      };
  
-     class MainClockView : public UICardPage
+     class MainClockView : public UICardPage 
      {
      public:
          MainClockView();
  
          void UpdateStateShow(void);
  
+ 
+         void ScrollBegin(bool isActive) override;
+         void ScrollEnd(bool isActive) override;
+         void CoverBegin(bool isCovered) override;
+         void CoverEnd(bool isCovered) override;
+         void OnActive(void) override;
+         void OnInactive(void) override;
+ 
      private:
          void InitStepValue();
          bool InitLabelView(void);
  
          /*表盘背景*/
          UIImageView *curFace{nullptr};
+         DialVideoView* videoPlayer_ = nullptr;
+         UILiteSurfaceView *surfaceView_ = nullptr;
          
          /*时间相关*/
          UILabel *timerlabel{nullptr};
          BatteryDisplayType batterySetting = BATTERY_DISPLAY_NONE; // 电池设置
          TimeDisplayPosition timePosition = TIME_DISPLAY_DEFAULT;  // 时间位置
          int64_t color_ = Color::White().full;                     // 电量颜色
-         int32_t power_ = 101;                                      // 电量
+         int32_t power_ = 101;                                     // 电量
          bool isBatteryIconVisible{false};                         // 电池暂停
+         uint8_t custom_id = 0;
      };
  } // namespace OHOS
  #endif // MAIN_CLOCK_VIEW_H
index dd2b957..da20658 100644 (file)
 #include "main/include/PullUpDownView.h"
 #include "message/include/MessageControlView.h"
 #include "uicomponents/UIComponents.h"
+ #include "components/ui_lite_surface_view.h"
+ #include "video_play_wrapper.h"
 
  #include "ui_resource_image.h"
- 
  #include "wearable_log.h"
  #include <cwchar>
  #include <iomanip>
  #endif
      static constexpr uint16_t STEP_CHAR_NUM = 255;
      static MainClockView *g_pMainClockView = nullptr;
+     static constexpr int16_t JPEG_HEIGHT_DIVISOR = 2;
+     static constexpr int16_t JPEG_WIDTH_BYTE_ALIGNMENT = 128;
+     static constexpr int16_t JPEG_HEIGHT_BYTE_ALIGNMENT = 16;
+     static constexpr int16_t BUFFER_QUEUE_SIZE = 2;
+     static constexpr int16_t STRIDE_ALIGNMENT_VALUE = 128;
+ 
+     static inline int32_t MediaByteAlign(int16_t value, int16_t align)
+     {
+         return (((value) + (align) - 1) & (~((align) - 1)));
+     }
+ 
      MainClockView::MainClockView()
      {
          WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MainClockView::MainClockView");
            delete dialstateicon_;
            dialstateicon_ = nullptr;
          }
- 
          if (messageicon_ != nullptr) {
            delete messageicon_;
            messageicon_ = nullptr;
          }
+         if (videoPlayer_ != nullptr) {
+             delete videoPlayer_;
+             videoPlayer_ = nullptr;
+         }
  
          g_pMainClockView = nullptr;
      }
          if (Id == DIAL_CLOCK || Id > DIAL_MAX)
              return;
  
+         //赋值id
+         custom_id = Id;
+ 
          DialLayout dialconfig;
-         if (SetDialModel::GetInstance().loadDialConfig(Id, dialconfig))
+         if (SetDialModel::GetInstance().loadDialConfig(custom_id, dialconfig))
          {
-             // 设置背景
-             dialFile = SetDialModel::GetInstance().GetSaveDir(Id) + "/" + "main_bg.bin";
+             // 设置背景 Id == 2(实际是1) 视频表盘
+             if(Id == 2)
+             {
+                 dialFile = SetDialModel::GetInstance().GetSaveDir(custom_id) + "/" + "main_bg.mp4";
+             }
+             else // 图片表盘
+             {
+                 dialFile = SetDialModel::GetInstance().GetSaveDir(custom_id) + "/" + "main_bg.bin";
+             }
              WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "dialFile is %s", dialFile.c_str());
  
              // 设置表盘配置
              timePosition = static_cast<TimeDisplayPosition>(dialconfig.timeDisplay);
              batterySetting = static_cast<BatteryDisplayType>(dialconfig.batteryDisplay);
              colorType = static_cast<ColorTypeSet>(dialconfig.colorTypeSet);
+ 
+             //打印表盘配置
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "timePosition is %d", timePosition);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "batterySetting is %d", batterySetting);
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "colorType is %d", colorType);
          }
          else
          {
          InitColor(colorType);
          return true;
      }
-     /*初始化表盘背景*/
-     bool MainClockView::InitBackground(const char *filename) {
  
+     /*初始化表盘背景 图片 视频*/
+     bool MainClockView::InitBackground(const char *filename) {
          if (filename == nullptr) {
              WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "filename is null");
              return false;
          }
-         curFace = new UIImageView();
-         if (curFace == nullptr)
-         {
-             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "curFace new fail");
-             return false;
-         }
-         curFace->SetPosition(0, 0);
  
-         ImageCacheManager::GetInstance().UnloadSingleRes(filename);
-         ImageInfo *image = ImageCacheManager::GetInstance().LoadSingleRes(filename, false);
-         if (image == nullptr)
-         {
-             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadAllDialFromRam loadimage %s fail",
-                             filename);
-             curFace->SetSrc(DEFAULT_DIALBACK_PATH);
+         // 判断是否为视频表盘(图片表盘后缀为.bin,视频表盘后缀为.mp4)
+         const char* ext = strrchr(filename, '.');
+         bool isVideo = (ext != nullptr && strcasecmp(ext, ".mp4") == 0);
+ 
+         if (isVideo) {
+             // 判断文件是否存在
+             if (access(filename, F_OK) == -1) {
+                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error: The specified video file does not exist: %s", filename);
+                 return false;
+             }
+ 
+             // 检查视频播放器是否已初始化
+             if (videoPlayer_ != nullptr) {
+                 GRAPHIC_LOGE("Cannot set video res repeatedly!\n");
+                 return false;
+             }
+ 
+             // 打开视频文件
+             FILE* fp = fopen(filename, "rb");
+             if (fp == nullptr) {
+                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open video file: %s", filename);
+                 return false;
+             }
+ 
+             videoPlayer_ = new DialVideoView();
+             videoPlayer_->SetPosition(0 ,0,466, 466);
+             videoPlayer_->SetSurfaceColorkey(Color::GetColorFromRGBA(0xff,0x21,0x23,0x24));
+             videoPlayer_->SetVideoRes(fp, 0);
+             //阅览帧 preview.bin
+             std::string preview_img = SetDialModel::GetInstance().GetSaveDir(custom_id) + "/" + "preview.bin";
+             ImageInfo *image = ImageCacheManager::GetInstance().LoadSingleRes(preview_img.c_str(), false);
+             if (image != nullptr) {
+                 videoPlayer_->SetPreview(image);
+             }
+             else
+             {
+               WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadAllDialFromRam loadimage %s fail", preview_img.c_str());
+               return false;
+             }
+             Add(videoPlayer_);
+             return true;
+         } else {
+             // 处理图片表盘
+             curFace = new UIImageView();
+             if (curFace == nullptr) {
+                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "curFace new fail");
+                 return false;
+             }
+             curFace->SetPosition(0, 0);
+ 
+             ImageCacheManager::GetInstance().UnloadSingleRes(filename);
+             ImageInfo *image = ImageCacheManager::GetInstance().LoadSingleRes(filename, false);
+             if (image == nullptr) {
+                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadAllDialFromRam loadimage %s fail", filename);
+                 curFace->SetSrc(DEFAULT_DIALBACK_PATH);
+                 Add(curFace);
+                 return false;
+             }
+             curFace->SetSrc(image);
              Add(curFace);
-             return false;
+             return true;
          }
-         curFace->SetSrc(image);
-         Add(curFace);
-         return true;
      }
- 
      /*
          时间显示 [时间 日期 星期]
          0 显示在表盘上方
          Add(timerlabel);
          Add(datelabel);
          // Add(weekLabel);
-
-        //  timerlabel->SetWorkMode(UISweepClock::WorkMode::NORMAL);
          return true;
      }
      /*
            
              /*增加手表状态图标*/
              InitImageView(dialstateicon_, 213, 2, 40, 40, "disturbicon", DISTURBICON);
-             dialstateicon_->SetVisible(false);
  
              /*增加未读图标*/
              InitImageView(messageicon_, 223, 444, 20, 20, "messageicon_", MESSAGEICON);
  
          if (!resLoadStatus)
          {
-            //  if (PullUpDownView::GetInstance() != nullptr)
-            //  {
-            //      PullUpDownView::GetInstance()->PreLoad();
-            //  }
-            //  if (MessageControlView::GetInstance() != nullptr)
-            //  {
-            //      MessageControlView::GetInstance()->PreLoad();
-            //  }
+             if (PullUpDownView::GetInstance() != nullptr)
+             {
+                 PullUpDownView::GetInstance()->PreLoad();
+             }
+             if (MessageControlView::GetInstance() != nullptr)
+             {
+                 MessageControlView::GetInstance()->PreLoad();
+             }
              resLoadStatus = true;
          }
      }
  
          if (resLoadStatus)
          {
-            //  if (PullUpDownView::GetInstance() != nullptr)
-            //  {
-            //      PullUpDownView::GetInstance()->UnLoad();
-            //  }
+             if (PullUpDownView::GetInstance() != nullptr)
+             {
+                 PullUpDownView::GetInstance()->UnLoad();
+             }
  
-            //  if (MessageControlView::GetInstance() != nullptr)
-            //  {
-            //      MessageControlView::GetInstance()->UnLoad();
-            //  }
+             if (MessageControlView::GetInstance() != nullptr)
+             {
+                 MessageControlView::GetInstance()->UnLoad();
+             }
              resLoadStatus = false;
          }
      }
          struct tm local_time = {0};  
          time_t seconds = time(nullptr);  
  
-         // Get local time  
          if (localtime_r(&seconds, &local_time) == nullptr) {  
              WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "get localtime error!");  
              return;  
          }  
  
-         // Extract hour and minute  
          uint8_t hour = local_time.tm_hour % HOURS_IN_DAY;
          uint8_t minute = local_time.tm_min % MINUTES_IN_HOUR;
          char timebuf[64] = {0};  
              sprintf_s(timebuf, sizeof(timebuf), "%02d:%02d", hour, minute);
          #endif  
  
-         // Update display labels  
          if (timerlabel != nullptr)  
              timerlabel->SetText(timebuf);  
  
-         // Update date and week day  
+         
          std::string weekStr = Cnweekdays[local_time.tm_wday];  
          std::string dateStr = std::to_string(local_time.tm_mon + 1) + "月" +  
                              std::to_string(local_time.tm_mday) + "号 " + weekStr;  
          if (datelabel != nullptr)  
              datelabel->SetText(dateStr.c_str());  
  
-         // Update battery status  
+ 
+         //电量显示配置
          if (batterySetting == BATTERY_DISPLAY_NONE)  
              return;  
+      
  
          UpdateBatteryColor();  
  
          view->SetSrc(image);
          return true;
      }
+ 
+     void MainClockView::ScrollBegin(bool isActive)
+     {
+         if (videoPlayer_ == nullptr)
+         {
+             return;
+         }
+         if (videoPlayer_->IsPlayed())
+         {
+             videoPlayer_->PausePlay();
+         }
+     }
+ 
+     void MainClockView::ScrollEnd(bool isActive)
+     {
+         if (videoPlayer_ == nullptr)
+         {
+             return;
+         }
+ 
+         if (isActive)
+         {
+             if (videoPlayer_->IsPaused())
+             {
+                 videoPlayer_->ResumePlay();
+             }
+             else if (!videoPlayer_->IsPlayed())
+             {
+                 videoPlayer_->StartPlay();
+             }
+         }
+         else
+         {
+             if (videoPlayer_->IsPaused() || videoPlayer_->IsPlayed())
+             {
+                 videoPlayer_->StopPlay();
+             }
+             ClearCache();
+         }
+     }
+ 
+     void MainClockView::CoverBegin(bool isCovered)
+     {
+         if (videoPlayer_ == nullptr)
+         {
+             return;
+         }
+ 
+         if (videoPlayer_->IsPlayed())
+         {
+             videoPlayer_->PausePlay();
+         }
+     }
+ 
+     void MainClockView::CoverEnd(bool isCovered)
+     {
+         if (videoPlayer_ == nullptr)
+         {
+             return;
+         }
+         if (isCovered)
+         {
+             return;
+         }
+         else
+         {
+             if (videoPlayer_->IsPaused())
+             {
+                 videoPlayer_->ResumePlay();
+             }
+             else if (!videoPlayer_->IsPlayed())
+             {
+                 videoPlayer_->StartPlay();
+             }
+         }
+     }
+ 
+     void MainClockView::OnActive(void)
+     {
+         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "OnActive");
+         if (videoPlayer_ != nullptr)
+         {
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "OnActive videoPlayer_");
+             if (videoPlayer_->IsPaused())
+             {
+                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "OnActive videoPlayer_ resume");
+                 videoPlayer_->ResumePlay();
+             }
+             else if (!videoPlayer_->IsPlayed())
+             {
+                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "OnActive videoPlayer_ start");
+                 videoPlayer_->StartPlay();
+             }
+         }
+     }
+ 
+     void MainClockView::OnInactive(void)
+     {
+         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "OnInactive");
+         if (videoPlayer_ != nullptr)
+         {
+             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "OnInactive videoPlayer_");
+             if (!videoPlayer_->IsStopped())
+             {
+                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "OnInactive videoPlayer_ stop");
+                 videoPlayer_->StopPlay();
+             }
+         }
+     }
  }
  
\ No newline at end of file
index 4378e2d..2e152e4 100644 (file)
@@ -235,14 +235,21 @@ static errcode_t get_app_file_path(char* input_filename ,uint32_t input_size, ch
 }\r
 static errcode_t get_custom_dial_file_path(uint16_t id,char *filename,uint32_t input_size, char* output_file_path , uint32_t max_output_size)\r
 {\r
-    if( id >=5  || output_file_path == NULL)\r
+    if( id >=5  || output_file_path == NULL || filename == NULL)\r
     {\r
         return ERRCODE_FAIL;\r
     }\r
     char name[64]={0};\r
     ble_get_dial_path(name,id);\r
-\r
-    int ret = sprintf_s(output_file_path,max_output_size,"%s/%s.bin",name,filename);\r
+    int ret;\r
+   if(id == 1 && strcmp(filename, "main_bg") == 0) //自定义视频表盘Id 1 只有背景需要是mp4 main_bg\r
+    {\r
+        ret = sprintf_s(output_file_path,max_output_size,"%s/%s.mp4",name,filename);  \r
+    }\r
+    else\r
+    {\r
+        ret = sprintf_s(output_file_path,max_output_size,"%s/%s.bin",name,filename);\r
+    }\r
     if (ret < 0)\r
         return ERRCODE_FAIL;\r
 \r