1.Abilitty文件PostChangeSlice函数添加特俗判断:如果TransitionType 为TRANSITION_HEXAGONS清除按键监听,解决app...
authorluozheng <1732036298@qq.com>
Fri, 21 Jun 2024 13:07:01 +0000 (21:07 +0800)
committerluozheng <1732036298@qq.com>
Fri, 21 Jun 2024 13:07:01 +0000 (21:07 +0800)
2.HexagonsTransition 文件修改,解决applist样式为蜂窝旋转表冠进入slice卡死问题
3修改OnRotateEvent函数

15 files changed:
code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoiceBluetoothFailedStartView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoicePresenter.h
code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoiceView.h
code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceBluetoothFailedStartView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoicePresenter.cpp
code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceView.cpp
code/sdk/application/wearable/fd230app/nativeui/applist/src/ApplistPresenter.cpp
code/sdk/application/wearable/fd230app/nativeui/applist/src/ApplistView.cpp
code/sdk/application/wearable/nativeabilityfwk/src/Ability.cpp
code/sdk/application/wearable/nativeabilityfwk/src/transition/HexagonsTransition.cpp
code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/AIVoice/AI_EllWhite.bin [new file with mode: 0644]
code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/AIVoice/AI_RecBlack.bin [moved from code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/AIVoice/AIRecBlack.bin with 100% similarity]
code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/AIVoice/AI_RecGreen.bin [moved from code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/AIVoice/AIRecGreen.bin with 100% similarity]
code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/AIVoice/AI_Union.bin [moved from code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/AIVoice/AIUnion.bin with 100% similarity]
code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/components/ui_custom_hexagons_list.cpp

diff --git a/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoiceBluetoothFailedStartView.h b/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoiceBluetoothFailedStartView.h
new file mode 100644 (file)
index 0000000..e69de29
index 94b32d2..f15db76 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-06-20 14:44:22
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-20 15:25:08
+ * @LastEditTime: 2024-06-21 15:32:01
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoicePresenter.h
  */
 #ifndef AI_VOICE_PRESENTER_H
@@ -26,8 +26,8 @@ namespace OHOS
         static AiVoicePresenter *GetInstance();
 
         void OnStart() override;
-        void OnPause() override;
         void OnResume() override;
+        void OnPause() override;
         void OnStop() override;
 
 
index 7e23752..12e1a20 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-06-08 09:36:01
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-20 19:53:13
+ * @LastEditTime: 2024-06-21 16:35:00
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/AiVoiceView.h
  */
 #ifndef AI_VOICE_VIEW_H
 #include "View.h"
 #include "components/ui_label_ext.h"
 #include "components/ui_button.h"
-
+#include "components/ui_scroll_view.h"
+#include "components/ui_image_view.h"
 namespace OHOS
 {
+    static constexpr const char *START_CHAT_BUTTON_VIEW_ID = "StartChatButton"; // 开始对话
+
+    typedef enum
+    {
+        AIVOICE_STARTCHAT_VIEWID = 0,          // 开始对话界面
+        AIVOICE_BLUETOOTH_FAILEDSTART_VIEWID,  // 蓝牙未开启界面
+        AIVOICE_MOBILEDATA_FAILEDSTART_VIEWID, // 移动数据未开启界面
+        AIVOICE_CONNECT_TIMEOUT_VIEWID,        // 连接超时界面
+        AIVOICE_LISTENING_VIEWID,              // 聆听中界面
+        AIVOICE_THINKING_VIEWID,               // 思考中界面
+        AIVOICE_RETURN_RESULT_TEXT_VIEWID,     // 返回结果文本界面
+        MAX_AIVOICE_VIEWID,
+    } AIVOICEVIEWID;
+
     class AiVoicePresenter;
     class AiVoiceView : public View<AiVoicePresenter>
     {
@@ -32,6 +47,14 @@ namespace OHOS
             uint8_t lineBreakMode;
         };
 
+        struct ImageConfig
+        {
+            int16_t x;
+            int16_t y;
+            int16_t w;
+            int16_t h;
+        };
+
         struct ButtonConfig
         {
             int16_t x;
@@ -44,6 +67,15 @@ namespace OHOS
         AiVoiceView();
         ~AiVoiceView();
         static AiVoiceView *GetInstance(void);
+        bool ClickFunc(int16_t interface);
+        void ChangeView(int16_t hideView, int16_t showView);
+        bool ChangeAiVoiceStartChatView(int16_t thisView);
+        bool ChangeAiVoiceBluetoothFailedStartView(int16_t thisView);
+        bool ChangeAiVoiceMobileDataFailedStartView(int16_t thisView);
+        bool ChangeAiVoicConnectTimeoutView(int16_t thisView);
+        bool ChangeAiVoicListeningView(int16_t thisView);
+        bool ChangeAiVoicThinkingView(int16_t thisView);
+        bool ChangeAiVoicReturnResultTextView(int16_t thisView);
 
         void OnStart() override;
         void OnSetUpView() override;
@@ -52,14 +84,18 @@ namespace OHOS
 
     private:
         UILabelExt *AiVoiceViewLabelInit(LabelConfig &labelconfig);
+        UIImageView *AiVoiceViewImageView(ImageConfig &imageconfig);
         UIButton *AiVoiceViewLabelButtonInit(ButtonConfig &buttonconfig);
         bool CreateAiVoiceViewLabel(void);
+        bool CreateAiVoiceViewImageView(void);
         bool CreateAiVoiceViewButton(void);
         void CreateAiVoiceView(void);
         void ClearAll(void);
         UILabelExt *title{nullptr};
         UILabelExt *startChatLabel{nullptr};
         UIButton *startChatButton{nullptr};
+        UIImageView *startChatImage{nullptr};
+        UIScrollView *AiVoiceScrollView[MAX_AIVOICE_VIEWID]{nullptr};
 
         bool viewInitStatus{false};
     };
diff --git a/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceBluetoothFailedStartView.cpp b/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceBluetoothFailedStartView.cpp
new file mode 100644 (file)
index 0000000..e69de29
index 8ece842..b7bb011 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-06-20 15:11:17
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-20 16:52:30
+ * @LastEditTime: 2024-06-21 16:46:34
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoicePresenter.cpp
  */
 #include "AppViewIDs.h"
@@ -13,6 +13,7 @@
 #include "common/key_code.h"
 #include <custom_utils.h>
 #include "UiConfig.h"
+#include "iostream"
 
 namespace OHOS
 {
@@ -36,18 +37,14 @@ namespace OHOS
         return g_pAiVoicePresenter;
     }
 
+    // 启动时执行的逻辑
     void AiVoicePresenter::OnStart()
     {
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnStart");
         Presenter<AiVoiceView>::OnStart();
     }
 
-    void AiVoicePresenter::OnPause(void)
-    {
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnPause");
-        Presenter<AiVoiceView>::OnPause();
-    }
-
+    // 页面已经展示后的调用逻辑
     void AiVoicePresenter::OnResume(void)
     {
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnResume");
@@ -56,9 +53,16 @@ namespace OHOS
         {
             return;
         }
-        RootView::GetInstance()->SetOnKeyActListener(this);
     }
 
+    // 页面准备切换到后台前执行的逻辑
+    void AiVoicePresenter::OnPause(void)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnPause");
+        Presenter<AiVoiceView>::OnPause();
+    }
+
+    // 页面完全置于后台时的逻辑。
     void AiVoicePresenter::OnStop(void)
     {
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnStop");
@@ -69,6 +73,13 @@ namespace OHOS
     {
         UNUSED(event);
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnClick");
+        std::string viewId = view.GetViewId();
+
+        if (viewId == START_CHAT_BUTTON_VIEW_ID)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::START_CHAT_BUTTON_VIEW_ID");
+        }
+
         return true;
     }
 
index 1386fc2..51d6232 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-05-07 11:25:58
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-20 20:22:36
+ * @LastEditTime: 2024-06-21 16:53:20
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/AiVoice/src/AiVoiceView.cpp
  */
 #include "aivoice/include/AiVoicePresenter.h"
@@ -62,6 +62,17 @@ namespace OHOS
         return label;
     }
 
+    UIImageView *AiVoiceView::AiVoiceViewImageView(ImageConfig &imageconfig)
+    {
+        UIImageView *Image = new UIImageView();
+        if (Image == nullptr)
+        {
+            return nullptr;
+        }
+        Image->SetPosition(imageconfig.x, imageconfig.y, imageconfig.w, imageconfig.h);
+        return Image;
+    }
+
     UIButton *AiVoiceView::AiVoiceViewLabelButtonInit(ButtonConfig &buttonconfig)
     {
         UIButton *button = new UIButton();
@@ -118,6 +129,27 @@ namespace OHOS
         return true;
     }
 
+    bool AiVoiceView::CreateAiVoiceViewImageView(void)
+    {
+        ImageConfig imagecinfig = {
+            .x = 207,
+            .y = 182,
+            .w = 52,
+            .h = 52,
+        };
+        startChatImage = AiVoiceViewImageView(imagecinfig);
+        if (startChatImage == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::startChatImage is nullptr!!");
+            return false;
+        }
+        startChatImage->SetStyle(STYLE_BACKGROUND_COLOR, 0xffffffff);
+        startChatImage->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+        startChatImage->SetStyle(STYLE_BORDER_RADIUS, 100);
+
+        return true;
+    }
+
     bool AiVoiceView::CreateAiVoiceViewButton(void)
     {
         ButtonConfig buttonconfig = {
@@ -125,7 +157,7 @@ namespace OHOS
             .y = 340,
             .w = 280,
             .h = 90,
-            .ViewId = "StartChat",
+            .ViewId = START_CHAT_BUTTON_VIEW_ID,
         };
         startChatButton = AiVoiceViewLabelButtonInit(buttonconfig);
         if (startChatButton == nullptr)
@@ -140,12 +172,13 @@ namespace OHOS
     void AiVoiceView::CreateAiVoiceView(void)
     {
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::CreateAiVoiceView");
-        if (!CreateAiVoiceViewLabel() || !CreateAiVoiceViewButton())
+        if (!CreateAiVoiceViewLabel() || !CreateAiVoiceViewImageView() || !CreateAiVoiceViewButton())
         {
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::CreateAiVoiceView fail!");
             return;
         }
         container_->Add(title);
+        container_->Add(startChatImage);
         container_->Add(startChatButton);
         container_->Add(startChatLabel);
     }
@@ -155,6 +188,11 @@ namespace OHOS
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::OnStart");
         View<AiVoicePresenter>::OnStart();
         SetContainerView(new UIViewGroup());
+        if (container_ == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "container_ new fail!!");
+            return;
+        }
         container_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
         container_->SetOnDragListener(presenter_);
         container_->SetTouchable(true);
@@ -166,6 +204,7 @@ namespace OHOS
             viewInitStatus = true;
         }
 
+        RootView::GetInstance()->SetOnKeyActListener(presenter_);
         return;
     }
 
@@ -192,4 +231,112 @@ namespace OHOS
         ClearAll();
         return;
     }
+
+    /*切换到开始对话Ai界面*/
+    bool AiVoiceView::ChangeAiVoiceStartChatView(int16_t thisView)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoiceStartChatView");
+        if (AiVoiceScrollView[thisView] == nullptr)
+        {
+            container_->Add(AiVoiceScrollView[thisView]);
+        }
+        return true;
+    }
+
+    /*切换到蓝牙未开启界面*/
+    bool AiVoiceView::ChangeAiVoiceBluetoothFailedStartView(int16_t thisView)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoiceBluetoothFailedStartView");
+
+        return true;
+    }
+
+    /*切换到移动数据未开启界面*/
+    bool AiVoiceView::ChangeAiVoiceMobileDataFailedStartView(int16_t thisView)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoiceMobileDataFailedStartView");
+
+        return true;
+    }
+
+    /*切换到连接超时界面*/
+    bool AiVoiceView::ChangeAiVoicConnectTimeoutView(int16_t thisView)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoicConnectTimeoutView");
+
+        return true;
+    }
+
+    /*切换到聆听中界面*/
+    bool AiVoiceView::ChangeAiVoicListeningView(int16_t thisView)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoicListeningView");
+
+        return true;
+    }
+
+    /*切换到思考中界面*/
+    bool AiVoiceView::ChangeAiVoicThinkingView(int16_t thisView)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoicThinkingView");
+
+        return true;
+    }
+
+    /*切换到返回结果文本界面*/
+    bool AiVoiceView::ChangeAiVoicReturnResultTextView(int16_t thisView)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoicReturnResultTextView");
+
+        return true;
+    }
+
+    struct AiVoiceViewMapper
+    {
+        const int16_t viewId;
+        bool (AiVoiceView::*func)(int16_t thisView);
+    };
+
+    static const AiVoiceViewMapper ViewMapper[] = {
+        {AIVOICE_STARTCHAT_VIEWID, &AiVoiceView::ChangeAiVoiceStartChatView},
+        {AIVOICE_BLUETOOTH_FAILEDSTART_VIEWID, &AiVoiceView::ChangeAiVoiceBluetoothFailedStartView},
+        {AIVOICE_MOBILEDATA_FAILEDSTART_VIEWID, &AiVoiceView::ChangeAiVoiceMobileDataFailedStartView},
+        {AIVOICE_CONNECT_TIMEOUT_VIEWID, &AiVoiceView::ChangeAiVoicConnectTimeoutView},
+        {AIVOICE_LISTENING_VIEWID, &AiVoiceView::ChangeAiVoicListeningView},
+        {AIVOICE_THINKING_VIEWID, &AiVoiceView::ChangeAiVoicThinkingView},
+        {AIVOICE_RETURN_RESULT_TEXT_VIEWID, &AiVoiceView::ChangeAiVoicReturnResultTextView},
+    };
+
+    bool AiVoiceView::ClickFunc(int16_t interface)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ClickFunc");
+        int funcSize = sizeof(ViewMapper) / sizeof(ViewMapper[0]);
+        for (int i = 0; i < funcSize; i++)
+        {
+            if (interface == ViewMapper[i].viewId)
+            {
+                bool jug = (this->*(ViewMapper[i].func))(interface);
+                if (jug == false)
+                {
+                    return false;
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    void AiVoiceView::ChangeView(int16_t hideView, int16_t showView)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeView");
+        if (hideView > MAX_AIVOICE_VIEWID)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Overstep ones bounds");
+            return;
+        }
+        AiVoiceScrollView[hideView]->SetVisible(false);
+        ClickFunc(showView);
+        AiVoiceScrollView[showView]->SetVisible(true);
+        Draw();
+    }
 }
\ No newline at end of file
index 644c540..894097b 100644 (file)
@@ -74,7 +74,7 @@ namespace OHOS {
 
     bool ApplistPresenter::OnRotate(UIView& view, const RotateEvent& event)
     {
-        #if 0 //取消放大进入应用
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApplistPresenter::OnRotate");
         UICustomHexagonsList* hexagonsView = dynamic_cast<UICustomHexagonsList *>(&view);
         if (hexagonsView == nullptr) {
             return false;
@@ -94,7 +94,6 @@ namespace OHOS {
             NativeAbility::GetInstance().EnterSlice(viewId, TransitionType::TRANSITION_HEXAGONS);
             hexagonsView->ClearFocus();
         }
-        #endif
         return true;
     }
 
index c01a756..2ffae53 100644 (file)
@@ -164,6 +164,7 @@ void ApplistView::OnStop()
     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApplistView::OnStop");
     if (presenter_->GetIsUseListStyle()) {
         ListStyleOnStop();
+        RootView::GetInstance()->ClearOnKeyActListener();
     } else {
         HexagonsStyleOnStop();
     }
@@ -173,7 +174,7 @@ void ApplistView::OnStop()
         delete container_;
         container_ = nullptr;
     }
-    RootView::GetInstance()->ClearOnKeyActListener();
+    //RootView::GetInstance()->ClearOnKeyActListener();
     //FocusManager::GetInstance()->ClearFocus();
     return;
 }
index 0df25d5..114fc4b 100755 (executable)
@@ -18,6 +18,8 @@
 #include "abilityms_slite_client.h"
 #include "common/input_device_manager.h"
 #include "dock/focus_manager.h"
+#include <TransitionType.h>
+#include "BaseView.h"
 namespace OHOS {
 /*
  * @brief 负责将一个SliceProxy对象添加到Ability对象中,如果传入的sliceId是无效的或者代理对象proxy为空,则不执行任何操作。
@@ -135,6 +137,10 @@ void Ability::PostChangeSlice(const uint16_t targetSliceId, TransitionType type,
     bool useTransition = sliceTransition_.SetTransitionType(type);
     bool isCurSnapshotEnabled = sliceTransition_.IsCurrentSnapshotEnabled();
     FocusManager::GetInstance()->ClearFocus();
+    if(type == TransitionType::TRANSITION_HEXAGONS)
+    {
+        RootView::GetInstance()->ClearOnKeyActListener();
+    }
 
     if (!useTransition) {
         StopSlice();
@@ -177,7 +183,7 @@ void Ability::PostChangeSlice(const uint16_t targetSliceId, TransitionType type,
 
 void Ability::OnTransitionEnd()
 {
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability::OnTransitionEnd");
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability::OnTransitionEnd");
     if (!sliceTransition_.IsCurrentSnapshotEnabled()) {
         if (prevSlice_.slice != nullptr) {
             prevSlice_.slice->OnStop();
index 8095361..863b6e8 100644 (file)
@@ -53,7 +53,7 @@ void HexagonsTransition::OnTransitionStart(UIView* current, UIImageView* target)
     uint32_t offsetTime = static_cast<uint32_t>((scaleStart_ - HEXAGONS_SCALE_INIT) /
         (scaleEnd_ - HEXAGONS_SCALE_INIT) * duration_);
     durationBackup_ = duration_;
-    duration_ = duration_ - offsetTime;
+    duration_ = (duration_ > offsetTime) ? (duration_ - offsetTime) : (offsetTime - duration_);
     thresholdTime_ = static_cast<uint32_t>((HEXAGONS_SCALE_TRANSPARENT - scaleStart_) / (scaleEnd_ - scaleStart_)
         * duration_);
     xDistance_ = delta.x_;
diff --git a/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/AIVoice/AI_EllWhite.bin b/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/AIVoice/AI_EllWhite.bin
new file mode 100644 (file)
index 0000000..fd341b1
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:98c7ab619ae0b6d361b7ef216f7061e591007029c39483b7626203cb2bf48002
+size 264
index 2b578d7..33b1e69 100644 (file)
@@ -122,6 +122,16 @@ bool UICustomHexagonsList::OnRotateEvent(const RotateEvent& event)
 {
     float deltaScale = event.GetRotate() * ROTATE_SCALE_FACTOR;
     float targetScale = globalScale_ + deltaScale;
+    /* -------------------------------------------------------------------------- */
+    int8_t focusIndex = GetFocusedImgIndex();
+    //printf("%d\n",focusIndex);
+    if (focusIndex < 0) {
+        GRAPHIC_LOGE("wrong focus index %d, force to be 0 !!", focusIndex);
+        rotateCenterIndexInNormal_ = 0;
+    } else {
+        rotateCenterIndexInNormal_ = static_cast<uint8_t>(focusIndex);
+    }
+    /* -------------------------------------------------------------------------- */
     Vector2<int16_t> position = GetCurrentPosition(rotateCenterIndexInNormal_);
     Vector2<int16_t> deltaDistance;
     // Current scale > Normal(1.0f), scale and change opaque