--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-21 17:07:07
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-07-31 14:16:00
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoiceBluetoothFailedStartView.h
+ */
+
+#ifndef AI_VOICE_BLUETOOTH_FAILEDSTART_VIEW_H
+#define AI_VOICE_BLUETOOTH_FAILEDSTART_VIEW_H
+
+#include "components/ui_scroll_view.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_button.h"
+#include "components/ui_image_view.h"
+
+namespace OHOS
+{
+ static constexpr const char *ALERT_APPBLUETOOTH_AND_4GNETWORK_ENSURE_BUTTON_VIEW_ID = "AppBluetoothAnd4gNetworkEnsureButton";//APP蓝牙与4G网络都连接异常界面的确定按钮
+
+ class AiVoiceBluetoothFailedStartView
+ {
+ public:
+ struct LabelConfig
+ {
+ int16_t left;
+ int16_t top;
+ int16_t width;
+ int16_t height;
+ int16_t fontSize;
+ int16_t lineHeigh;
+ uint16_t textId;
+ uint8_t lineBreakMode;
+ };
+ struct ButtonConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ const char *ViewId;
+ };
+
+ struct ImageConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ };
+
+ AiVoiceBluetoothFailedStartView();
+ ~AiVoiceBluetoothFailedStartView();
+ static AiVoiceBluetoothFailedStartView *GetInstance(void);
+ UIScrollView *CreateAiVoiceBluetoothFailedStartView(void);
+ void UpdateTitleTextId(int textId);
+
+ private:
+ void ClearAll(void);
+ UILabelExt *AiVoiceBluetoothFailedStartLabelInit(LabelConfig &labelconfig);
+ UIButton *AiVoiceBluetoothFailedStartButtonInit(ButtonConfig &buttonconfig);
+ UIImageView *AiVoiceBluetoothFailedStartImageInit(ImageConfig &imageconfig);
+ bool CreateAiVoiceBluetoothFailedStartLabel(void);
+ bool CreateAiVoiceBluetoothFailedStartButton(void);
+ bool CreateAiVoiceBluetoothFailedStartImage(void);
+ bool CreateAiVoiceBluetoothFailedStartScrollView(void);
+ UIScrollView *scrollView{nullptr};
+ UILabelExt *title{nullptr};
+ UIImageView *attentionImage{nullptr};
+ UILabelExt *label[2]{nullptr};
+ UILabelExt *ensure{nullptr};
+ UIButton *ensureButton{nullptr};
+ };
+}
+#endif
\ No newline at end of file
--- /dev/null
+/***
+ * @Date: 2024-08-19 19:20:08
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-08-30 18:57:30
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoiceConnectingView.h
+ */
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-08-03 11:09:56
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-08-31 15:11:11
+ * @FilePath: /xts_origin/FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoiceConnectingView.h
+ */
+
+#ifndef AIVOICE_CONNECTING_H
+#define AIVOICE_CONNECTING_H
+#include "components/ui_button.h"
+#include "components/ui_scroll_view.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_image_animator.h"
+namespace OHOS
+{
+ static constexpr const char *AIVOICECONNECTINGVIEW_CANCEL_BUTTON_VIEW_ID = "AivoiceConnectingcancelButton"; // 正在连接中界面取消按钮
+ static constexpr int16_t AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES = 60; // 图片帧数
+
+ class AiVoiceConnectingView
+ {
+ public:
+ struct LabelConfig
+ {
+ int16_t left;
+ int16_t top;
+ int16_t width;
+ int16_t height;
+ int16_t fontSize;
+ int16_t lineHeigh;
+ uint16_t textId;
+ uint8_t lineBreakMode;
+ };
+ struct ButtonConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ const char *viewId;
+ };
+
+ struct ImageAnimatorConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t width;
+ int16_t height;
+ ImageAnimatorInfo *imageInfoArray;
+ const ImageInfo **pathsArray;
+ uint8_t numFrames;
+ int delay;
+ };
+
+ AiVoiceConnectingView();
+ ~AiVoiceConnectingView();
+ static AiVoiceConnectingView *GetInstance(void);
+ UIScrollView *CreateAiVoiceConnectingView(void);
+ UIScrollView *CreateAiVoiceConnectingView(uint8_t);
+
+ private:
+ UIImageAnimatorView *connectingImageAnimatorInit(ImageAnimatorConfig &imageanimatorconfig);
+ UILabelExt *AiVoiceConnectingViewLabelInit(LabelConfig &labelconfig);
+ UIButton *AiVoiceConnectingViewButtonInit(ButtonConfig &buttonconfig);
+ bool CreateAiVoiceConnectingViewLabel(void);
+ bool CreateAiVoiceConnectingViewButton(void);
+ bool CreateAivoiceConnectingImageAnimator(void);
+ bool CreateAiVoiceConnectingScrollView(void);
+ bool CreateAiVoiceConnectingScrollView(uint8_t);
+ void ClearAll(void);
+ UIScrollView *scrollView{nullptr};
+ UILabelExt *title{nullptr};
+ UILabelExt *cancelLabel{nullptr};
+ UIButton *cancelButton{nullptr};
+ UIImageAnimatorView *connectingAnimatorView{nullptr};
+ ImageAnimatorInfo connectingImageInfo[AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES];
+ const ImageInfo **connectingPathsArray{nullptr};
+ };
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-20 15:14:43
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2025-03-19 09:44:14
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoiceModel.h
+ */
+#ifndef AI_VOICE_MODEL_H
+#define AI_VOICE_MODEL_H
+
+#include "iostream"
+#include "string"
+#include "iostream"
+#include "string"
+#include "ChatContentItem.h"
+#include "map"
+#define AIAUDIO_TYPE_PCM 0
+#define AIAUDIO_TYPE_SBC 1
+#define AIAUDIO_TYPE_MSBC 2
+
+// 设置当前使用的音频类型,0 表示 PCM,1 表示 SBC,2 表示 MSBC
+#define CURRENT_AIAUDIO_TYPE AIAUDIO_TYPE_SBC
+
+namespace OHOS
+{
+
+ class AiVoiceModel
+ {
+ public:
+ enum aiResponseType :uint8_t {
+ AI_RECORDING_PARSING_ERROR = 0, //AI录音解析错误
+ AI_RECORDING_PARSING_CONTENT, //AI录音解析内容
+ AI_RESPONSE_CONTENT, //AI回应内容
+ AI_RESPONSE_ERROR,//AI 回应错误
+ AI_RESPONSE_END,//AI 回应结束
+ AI_BLE_ERROR,//蓝牙数据传入错误
+ };
+
+ static AiVoiceModel &GetInstance(void); // 获取单例实例
+ bool ChangeToReturnResultTextView(void);
+ bool ChangeToAIVoiceListeningView(bool value);
+ bool ChangeToAIVoiceConnectTimeoutView();
+ void FunctionKeyOnClickToChangeAIModel(void);
+ // 初始化和状态管理
+ void StatusResume(void);
+
+ bool IsExistOpenAIAPIKeys();
+ void DeleteLocalOpenAIAPIKeys();
+ bool GetAPPBluetoothIsConnect(void);
+ bool GetMobileDataIsOpen(void);
+ bool GetAiVoiceConnectStatus(void);
+ void SetAiVoiceConnectStatus(bool state);
+ void QuerySelectedAiModelIsConnect();
+ void CancelCurAIChat(void);
+ int GetAIResponseType(void);
+ std::string GetErrnote(void);
+ void SetErrnote(std::string str);
+ void SetCurView(int16_t viewNum);
+ int GetCurView(void);
+
+ // 聊天内容管理
+ bool InitchatContentItems(void);
+ bool AddUserQuestionToChatItems();
+ bool AddAiAnswerToChatItems();
+ bool AddChatContentToItemArray(const ChatContentItem &item);
+ uint8_t GetChatContentListCount(void);
+
+ // 更新和清空问题及回答
+ bool RemoveLastTwoItemsOrClear();
+ bool UpdateUserQuestionStr(void);
+ bool UpdateAiAnswerStr(void);
+ void ClearQuestionAndAiAnswerStr(void);
+
+ // 获取和设置问题及回答
+ std::string GetUserQuestionStr(void);
+ void SetUserQuestionStr(std::string str);
+ std::string GetAiAnswerStr(void);
+ void SetAiAnswerStrStr(std::string str);
+ void SetAiAnswerStrStr(std::string str,uint8_t type);
+ uint8_t GetCurUsingAiModelType(void);
+
+ // 文件检查和AI状态管理
+ void CheckFileAndSendAIIsReady();
+ //发送AI已经就绪(继续对话时候使用)
+ void sendAIIsReady();
+
+ // AI录音路径管理
+ std::string GetAIAudioPath(void);
+
+ // 启动和停止录音
+ void StartListenAndRecordingUserQuestion(void);
+ void StopListenAndRecordingUserQuestion(void);
+
+ // 定时器管理
+ void AIVoice_StartTimer(uint32_t interval = 1000);
+ void AIVoice_StopTimer(void);
+
+ void ai_start_screen60s_timer(uint32_t interval = 30*1000);
+ void ai_stop_screen60s_timer(void);
+ void reset_ai_screen60s_timer_time();
+ bool get_screen60s_timer_is_stop(void);
+
+ void start_listening_timer(uint32_t interval = 1000);
+ void stop_listening_timer(void);
+
+ void start_ai_isready_timer(uint32_t interval = 1000);
+ void stop_ai_isready_timer(void);
+
+ void SetSelectAiModel(int index);
+ int GetSelectAiModel(void);
+ int GetAiModelTextId(void);
+
+ bool CreateDirectory(const char* path);
+
+ void SetIsClickable(bool value);
+ bool GetIsClickable(void);
+
+ void SetIsLimitDisplayed(bool value);
+ bool GetIsLimitDisplayed(void);
+
+ private:
+ AiVoiceModel();
+ ~AiVoiceModel();
+ AiVoiceModel(const AiVoiceModel &) = delete;
+ AiVoiceModel &operator=(const AiVoiceModel &) = delete;
+
+// 私有成员变量
+#if CURRENT_AIAUDIO_TYPE == AIAUDIO_TYPE_PCM
+ std::string AIAIAudioPath = "/user/userdata/AiRecording/AIAudio.pcm"; // AI录音的文件路径
+#elif CURRENT_AIAUDIO_TYPE == AIAUDIO_TYPE_SBC
+ std::string AIAIAudioPath = "/user/userdata/AiRecording/AIAudio.sbc"; // AI录音的文件路径
+#elif CURRENT_AIAUDIO_TYPE == AIAUDIO_TYPE_MSBC
+ std::string AIAIAudioPath = "/user/userdata/AiRecording/AIAudio.msbc"; // AI录音的文件路径
+#endif
+ std::string userQuestionStr; // 用户提出的问题
+ std::string aiAnswerStr; // AI回答的问题
+ uint8_t ChatContentListCount{0}; // 列表数量
+ static const uint16_t MaxChatContentListCount = 2; // 对话列表最大数量
+ ChatContentItem chatTtems[MaxChatContentListCount] = {0, "", false}; // 对话项数组
+ bool entryTextViewState{false}; // 进入返回结果界面的标志
+ std::map<int, std::pair<int, int>> selectAiModelToTextId; // pair的参数类型<模型的textid,查询模型是否可用id>
+ bool AiVoiceConnectStatus{false}; //与AI模型的连接状态
+ uint8_t AIResponseType;
+ std::string errnote; //错误信息
+ int16_t curView{0};
+ bool isClickable{false};
+ bool isLimitDisplayed{false};//AI答案是否显示到极限了
+ };
+
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-20 14:44:22
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2025-02-18 14:32:12
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoicePresenter.h
+ */
+#ifndef AI_VOICE_PRESENTER_H
+#define AI_VOICE_PRESENTER_H
+
+#include "Presenter.h"
+#include "View.h"
+#include "ui_resource_string.h"
+#include "components/ui_time_picker.h"
+#include "ModelListenerSample.h"
+namespace OHOS
+{
+ class AiVoiceView;
+ class AiVoiceModel;
+ class AiVoicePresenter : public Presenter<AiVoiceView>,
+ public UIView::OnClickListener,
+ public UIView::OnDragListener,
+ public RootView::OnKeyActListener,
+ public UIPicker::SelectedListener,
+ public UIView::OnTouchListener,
+ public ModelListenerSample
+ {
+ public:
+ typedef enum : uint8_t
+ {
+ AIMODES_WENXINYIYAN = 0, /*文心一言*/
+ AIMODES_KIMI, /*KIMI*/
+ AIMODES_DOUBAO, /*豆包*/
+ AIMODES_TONGYI_QIANWEN, /*通义千问->DeepSeek*/
+ AIMODES_IFLYTEK_SPARK, /*讯飞星火*/
+ AIMODES_CHATGPT, /*chatgpt*/
+ AIMODES_MAX_NUM,
+ } aimodels;
+ AiVoicePresenter();
+ virtual ~AiVoicePresenter();
+ static AiVoicePresenter *GetInstance();
+
+ void OnStart() override;
+ void OnResume() override;
+ void OnPause() override;
+ void OnStop() override;
+ void Notify() override;
+ void calculateChatContentItemViewHeight(std::string text, bool flag);
+
+ bool JumpToReturnResultTextView(void);
+ bool ChangeToAIVoiceListeningView(bool val);
+ bool ChangeToAIVoiceConnectTimeoutView();
+ bool ChangeViewAndLogicOperator(int16_t hideView, int16_t showView);
+ void FunctionKeyOnClickToChangeAIModel(void);
+ void DragLeftToRightChangeAIModel(void);
+ void DragRightToLetfChangeAIModel(void);
+
+ private:
+ bool OnClick(UIView &view, const ClickEvent &event) override;
+ bool OnPress(UIView& view, const PressEvent& event) override;
+ bool OnRelease(UIView &view, const ReleaseEvent &event) override;
+ bool OnDrag(UIView &view, const DragEvent &event) override;
+ bool OnDragEnd(UIView &view, const DragEvent &event) override;
+ bool OnKeyAct(UIView &view, const KeyEvent &event) override; // 增加按键事件
+ void OnPickerStoped(UIPicker &picker) override;
+
+ AiVoiceModel *model;
+ bool X_DRAG_FLAG{false};
+
+ int preHeight{0};
+ bool isScroll{false};
+ };
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-08 09:36:01
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2025-02-18 14:48:55
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/AiVoiceView.h
+ */
+#ifndef AI_VOICE_VIEW_H
+#define 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"
+#include "components/ui_picker.h"
+#include "aivoice/include/AiVoiceBluetoothFailedStartView.h"
+#include "aivoice/include/AivoiceMobileDataFailedStartView.h"
+#include "aivoice/include/AivoiceConnectTimeoutView.h"
+#include "aivoice/include/AivoiceListeningView.h"
+#include "aivoice/include/AivoiceThinkingView.h"
+#include "aivoice/include/AivoiceReturnResultTextView.h"
+#include "aivoice/include/apikeys/SetApiKeysView.h"
+#include "aivoice/include/apikeys/NotSetApiKeysView.h"
+#include "aivoice/include/apikeys/ApiKeysDeleteView.h"
+#include "aivoice/include/AiVoiceConnectingView.h"
+#include "ui_resource_string.h"
+#include "iostream"
+#include "string"
+#include "map"
+namespace OHOS
+{
+ /*图片路径*/
+ static constexpr const char *AIMODEL_WENXINYIYAN_PATH = "/user/res/AIVoice/aimodels/aimodels_wenxinyiyan.bin"; /*文心一言*/
+ static constexpr const char *AIMODEL_CHATGPT_ON_PATH = "/user/res/AIVoice/aimodels/aimodels_chatgpt.bin"; /*ChatGPT*/
+ static constexpr const char *AIMODEL_KIMI_PATH = "/user/res/AIVoice/aimodels/aimodels_kimi.bin"; /*KIMI*/
+ static constexpr const char *AIMODEL_DOUBAO_PATH = "/user/res/AIVoice/aimodels/aimodels_doubao.bin"; /*豆包*/
+ static constexpr const char *AIMODEL_TONGYI_QIANWEN_PATH = "/user/res/AIVoice/aimodels/aimodes_tongyi_qianwen.bin"; /*通义千问*/
+ static constexpr const char *AIMODEL_IFLYTEK_SPARK_PATH = "/user/res/AIVoice/aimodels/aimodes_iflytek_spark.bin"; /*讯飞星火*/
+ static constexpr const char *AIMODEL_DEEPSEEK_PATH = "/user/res/AIVoice/aimodels/aimodes_deepseek.bin"; /*deepseek*/
+
+ /*组件ID*/
+ static constexpr const char *AIVOICE_START_CHAT_BUTTON_VIEW_ID = "aivoice_start_chat_button_view_id"; // 开始对话
+ static constexpr const char *AIVOICE_CHAT_BUTTON_VIEW_ID = "aivoice_chat_button_view_id"; // 对话
+ static constexpr const char *AIVOICE_APIKEYS_BUTTON_VIEW_ID = "aivoice_apikeys_button_view_id"; // API Keys
+ static constexpr const char *AIVOICE_PICKER_VIEW_ID = "aivoice_picker_view_id";
+ static constexpr const char *AIVOICE_IMGAE_VIEW_ID = "aivoice_imgae_view_id";
+
+ typedef enum
+ {
+ AIVOICE_STARTCHAT_VIEWID = 0, // 开始对话界面
+ AIVOICE_ALERT_APPBLUETOOTH_AND_4GNETWORK_VIEWID, // APP蓝牙与4G网络都连接异常界面
+ AIVOICE_AIMODEL_CONNECT_FAILED_VIEWID, // 模型连接失败弹窗界面
+ AIVOICE_CONNECT_TIMEOUT_VIEWID, // 连接超时界面
+ AIVOICE_LISTENING_VIEWID, // 聆听中界面
+ AIVOICE_THINKING_VIEWID, // 思考中界面
+ AIVOICE_RETURN_RESULT_TEXT_VIEWID, // 返回结果文本界面
+ AIVOICE_SETAPIKEYS, // API Keys set界面
+ AIVOICE_NOTSETAPIKEYS, // API Keys notset界面
+ AIVOICE_APIKEYS_DELETE, // API Keys 删除界面
+ AIVOICE_AIMODE_CONNECTING, // AI Mode正在连接视图
+ MAX_AIVOICE_VIEWID,
+ } AIVOICEVIEWID;
+
+ static std::map<int, const char *> TextIdToImagePath = {
+ {STR_AIMODES_WENXINYIYAN, AIMODEL_WENXINYIYAN_PATH},
+ {STR_AIMODES_KIMI, AIMODEL_KIMI_PATH},
+ {STR_AIMODELS_DOUBAO, AIMODEL_DOUBAO_PATH},
+ // {STR_TONGYI_QIANWEN, AIMODEL_TONGYI_QIANWEN_PATH},
+ {STR_DEEPSEEK, AIMODEL_DEEPSEEK_PATH},
+ {STR_IFLYTEK_SPARK, AIMODEL_IFLYTEK_SPARK_PATH},
+ {STR_AIMODES_CHATGPT, AIMODEL_CHATGPT_ON_PATH},
+ };
+
+ class AiVoicePresenter;
+ class AiVoiceView : public View<AiVoicePresenter>
+ {
+
+ public:
+ struct LabelConfig
+ {
+ int16_t left;
+ int16_t top;
+ int16_t width;
+ int16_t height;
+ int16_t fontSize;
+ int16_t lineHeigh;
+ uint16_t textId;
+ uint8_t lineBreakMode;
+ };
+
+ struct ImageConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ const char *src;
+ };
+
+ struct ButtonConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ const char *ViewId;
+ };
+
+ AiVoiceView();
+ ~AiVoiceView();
+ static AiVoiceView *GetInstance(void);
+ UIScrollView *GetAiVoiceScrollView(int16_t index);
+ bool ClickFunc(int16_t interface);
+ bool CheckViewParam(int16_t hideView, int16_t showView);
+ void DestroyTempView(int16_t hideView);
+ 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);
+ bool ChangeAiVoicSetApiKeysView(int16_t thisView);
+ bool ChangeAiVoicNotSetApiKeysView(int16_t thisView);
+ bool ChangeAiVoicApiKeysDeleteView(int16_t thisView);
+ bool ChangeAiVoicConnectingView(int16_t thisView);
+
+ void SetAiVoiceViewAllComponentsVisibilityStatus();
+ void ChangeAiModelAndUpdateComponentsStatus(void);
+
+ void OnStart() override;
+
+
+ private:
+ AiVoiceBluetoothFailedStartView *p_AiVoiceBluetoothFailedStartView{nullptr};
+ AivoiceMobileDataFailedStartView *p_AivoiceMobileDataFailedStartView{nullptr};
+ AivoiceConnectTimeoutView *p_AivoiceConnectTimeoutView{nullptr};
+ AivoiceListeningView *p_AivoiceListeningView{nullptr};
+ AivoiceThinkingView *p_AivoiceThinkingView{nullptr};
+ AivoiceReturnResultTextView *p_AivoiceReturnResultTextView{nullptr};
+ SetApiKeysView *p_SetApiKeysView{nullptr};
+ NotSetApiKeysView *p_NotSetApiKeysView{nullptr};
+ ApiKeysDeleteView *p_ApiKeysDeleteView{nullptr};
+ AiVoiceConnectingView *p_AiVoiceConnectingView{nullptr};
+
+ private:
+ UILabelExt *AiVoiceViewLabelInit(LabelConfig &labelconfig);
+ UIImageView *AiVoiceViewImageView(ImageConfig &imageconfig);
+ UIButton *AiVoiceViewButtonInit(ButtonConfig &buttonconfig);
+ bool CreateAiVoiceViewLabel(void);
+ bool CreateAiVoiceViewImageView(void);
+ bool CreateAiVoiceViewButton(void);
+ bool CreateAiVoiceViewPicker(void);
+ bool CreateAiVoiceScrollView(void);
+ void CreateAiVoiceView(void);
+ void ClearAll(void);
+ void SetComponentVisibility(UIView *component, bool isVisible);
+ UILabelExt *title{nullptr}; /*标题*/
+ UILabelExt *startChatLabel{nullptr}; /*开始对话标签,暂时不用*/
+ UIButton *startChatButton{nullptr}; /*开始对话按钮*/
+ UILabelExt *chatLabel{nullptr}; /*对话标签,暂时不用*/
+ UIButton *chatButton{nullptr}; /*对话按钮*/
+ UIImageView *aiModelImage{nullptr}; /*ai模型图片*/
+ UIImageView *buttonBgImage{nullptr}; /*按钮背景图片*/
+ UIImageView *upImage{nullptr}; /*上拉箭头*/
+ UILabelExt *apiKeysLabel{nullptr}; /*API Keys标签,暂时不用*/
+ UIButton *apiKeysButton{nullptr}; /*API Keys按钮,,暂时不用*/
+ UIPicker *aiModelPicker{nullptr}; /*ai模型选择器*/
+ UIScrollView *AiVoiceScrollView[MAX_AIVOICE_VIEWID]{nullptr};
+ bool viewInitStatus{false};
+ };
+}
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-03-28 14:26:55
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-07-15 20:25:36
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/languagecode/include/AivoiceChatContentListAdapter.h
+ */
+#ifndef AIVOICE_CHAT_CONTENT_LIST_ADAPTER_H
+#define AIVOICE_CHAT_CONTENT_LIST_ADAPTER_H
+
+#include "components/abstract_adapter.h"
+#include "components/ui_label_button_ext.h"
+#include "components/ui_list.h"
+#include "languagecode/LanguageInit.h"
+#include "UiConfig.h"
+#include <list>
+#include "aivoice/include/AivoiceChatContentListItemView.h"
+#include "iostream"
+
+namespace OHOS
+{
+
+ class AivoiceChatContentListAdapter : public AbstractAdapter
+ {
+ public:
+ AivoiceChatContentListAdapter();
+ ~AivoiceChatContentListAdapter();
+
+ void SetData(std::list<ChatContentItem> &data);
+ void ClearData(void);
+ std::list<ChatContentItem> &GetChatContentItem();
+ virtual uint16_t GetCount(void) override;
+ virtual UIView *GetView(UIView *inView, int16_t index) override;
+ void AddListItem(const ChatContentItem &item);
+ void SetItemClickListener(UIView::OnClickListener *itemclicklistener);
+ void calculateChatContentItemViewHeight(std::string text, bool flag);
+
+ private:
+ std::list<ChatContentItem> listData;
+ UIView::OnClickListener *itemClickListener{nullptr};
+ int itemViewHeight{0};
+ bool aiAnswerFlag{false};
+ };
+
+}
+
+#endif
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-29 17:26:19
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-09-26 15:21:21
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AivoiceChatContentListItemView.h
+ */
+
+#ifndef AIVOICE_CHAT_CONTENT_LIST_ITEM_VIEW_H
+#define AIVOICE_CHAT_CONTENT_LIST_ITEM_VIEW_H
+
+#include "components/ui_view_group.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_scroll_view.h"
+#include "components/ui_image_view.h"
+#include "View.h"
+#include "iostream"
+#include "ChatContentItem.h"
+namespace OHOS
+{
+ class AivoiceChatContentListItemView : public UIViewGroup
+ {
+ public:
+ AivoiceChatContentListItemView(int viewHeight, bool isAiAnswerFalg);
+ ~AivoiceChatContentListItemView();
+ void SetItemInfo(const ChatContentItem &itemInfo);
+ void SetUpChild();
+ void ResetItemView(int viewHeight, bool isAiAnswerFlag);
+
+ private:
+ UILabel chatContentLabel;
+ UIImageView chatContentImage;
+ UIScrollView chatContentScrollView;
+ int m_viewHeight;
+ bool m_isAiAnswerFalg{false};
+ };
+}
+
+#endif
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-22 16:46:26
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-08-31 16:14:01
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AivoiceConnectTimeoutView.h
+ */
+
+#ifndef AIVOICE_CONNECT_TIMEOUT_VIEW_H
+#define AIVOICE_CONNECT_TIMEOUT_VIEW_H
+
+#include "components/ui_scroll_view.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_button.h"
+#include "components/ui_image_view.h"
+
+namespace OHOS
+{
+ static constexpr const char *AIVOICECONNECTTIMEOUT_ENSURE_BUTTON_VIEW_ID = "AivoiceConnectTimeoutEnsureButton"; // 连接超时界面确定按钮
+
+ class AivoiceConnectTimeoutView
+ {
+ public:
+ struct LabelConfig
+ {
+ int16_t left;
+ int16_t top;
+ int16_t width;
+ int16_t height;
+ int16_t fontSize;
+ int16_t lineHeigh;
+ uint16_t textId;
+ uint8_t lineBreakMode;
+ };
+ struct ButtonConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ const char *ViewId;
+ };
+
+ struct ImageConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ };
+
+ AivoiceConnectTimeoutView();
+ ~AivoiceConnectTimeoutView();
+ static AivoiceConnectTimeoutView *GetInstance(void);
+ UIScrollView *CreateAivoiceConnectTimeoutView(void);
+ void UpdateTitleTextId(int textId);
+ void UpdateNoteText();
+ private:
+ void ClearAll(void);
+ UILabelExt *AivoiceConnectTimeoutLabelInit(LabelConfig &labelconfig);
+ UIButton *AivoiceConnectTimeoutButtonInit(ButtonConfig &buttonconfig);
+ UIImageView *AivoiceConnectTimeoutImageInit(ImageConfig &imageconfig);
+ bool CreateAivoiceConnectTimeoutLabel(void);
+ bool CreateAivoiceConnectTimeoutButton(void);
+ bool CreateAivoiceConnectTimeoutImage(void);
+ bool CreateAivoiceConnectTimeoutScrollView(void);
+ UIScrollView *scrollView{nullptr};
+ UILabelExt *title{nullptr};
+ UIImageView *attentionImage{nullptr};
+ UILabelExt *NoteLabel{nullptr};
+ UILabelExt *ensure{nullptr};
+ UIButton *ensureButton{nullptr};
+ };
+}
+#endif
--- /dev/null
+/***
+ * @Date: 2024-06-26 16:59:51
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-08-30 18:57:36
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AivoiceListeningView.h
+ */
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-22 16:46:26
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-09-25 20:34:17
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AivoiceListeningView.h
+ */
+
+#ifndef AIVOICE_LISTENING_VIEW_H
+#define AIVOICE_LISTENING_VIEW_H
+
+#include "components/ui_scroll_view.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_button.h"
+#include "components/ui_image_view.h"
+#include "components/ui_image_animator.h"
+namespace OHOS
+{
+ static constexpr const char *FINISH_SPEAKING_BUTTON_VIEW_ID = "FinishSpeakingButton"; // 聆听中界面说话完毕按钮
+
+ static constexpr int16_t AIVOICE_LISTENING_IMAGE_ANIMATOR_VIEW_X = 113;
+ static constexpr int16_t AIVOICE_LISTENING_IMAGE_ANIMATOR_VIEW_Y = 178;
+ static constexpr int16_t AIVOICE_LISTENING_IMAGE_ANIMATOR_VIEW_W = 240;
+ static constexpr int16_t AIVOICE_LISTENING_IMAGE_ANIMATOR_VIEW_H = 60;
+ static constexpr int16_t AIVOICE_LISTENING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES = 40; // 图片帧数
+ static constexpr int16_t AIVOICE_LISTENING_IMAGE_ANIMATOR_DELAY = 70; // 图片更新间隔
+ static constexpr char *AIVoiceListeningImagePaths = "/user/res/AIVoice/AIVoiceListening/";
+ class AivoiceListeningView
+ {
+ public:
+ struct LabelConfig
+ {
+ int16_t left;
+ int16_t top;
+ int16_t width;
+ int16_t height;
+ int16_t fontSize;
+ int16_t lineHeigh;
+ uint16_t textId;
+ uint8_t lineBreakMode;
+ };
+ struct ButtonConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ const char *ViewId;
+ };
+
+ struct ImageAnimatorConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t width;
+ int16_t height;
+ ImageAnimatorInfo *imageInfoArray;
+ const ImageInfo **pathsArray;
+ uint8_t numFrames;
+ int delay;
+ };
+
+ AivoiceListeningView();
+ ~AivoiceListeningView();
+ static AivoiceListeningView *GetInstance(void);
+ UIScrollView *CreateAivoiceListeningView(void);
+ UILabelExt *GetShowtimeoutLabel(void);
+
+ private:
+ void ClearAll(void);
+ UILabelExt *AivoiceListeningLabelInit(LabelConfig &labelconfig);
+ UIButton *AivoiceListeningButtonInit(ButtonConfig &buttonconfig);
+ UIImageAnimatorView *AivoiceListeningImageAnimatorInit(ImageAnimatorConfig &imageanimatorconfig);
+ bool CreateAivoiceListeningLabel(void);
+ bool CreateAivoiceListeningButton(void);
+ bool CreateAivoiceListeningImageAnimator(void);
+ bool CreateAivoiceListeningScrollView(void);
+ UIScrollView *scrollView{nullptr};
+ UILabelExt *title{nullptr};
+ UILabelExt *finishSpeak{nullptr};
+ UIButton *finishSpeakButton{nullptr};
+ UIImageAnimatorView *AiVoiceListeningImageAnimatorView{nullptr};
+ ImageAnimatorInfo AiVoiceListeningImageInfo[AIVOICE_LISTENING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES];
+ const ImageInfo **AiVoiceListeningPathsArray{nullptr};
+ UILabelExt *showtimeout{nullptr};
+ };
+}
+#endif
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-22 15:22:56
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-07-31 15:08:31
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AivoiceMobileDataFailedStartView.h
+ */
+
+#ifndef AIVOICE_MOBILEDATA_FAILEDSTART_VIEW_H
+#define AIVOICE_MOBILEDATA_FAILEDSTART_VIEW_H
+
+#include "components/ui_scroll_view.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_button.h"
+#include "components/ui_image_view.h"
+
+namespace OHOS
+{
+ static constexpr const char *AIMODEL_CONNECT_FAILED_ENSURE_BUTTON_VIEW_ID = "AimodelConnectFailedEnsureButton_"; // 模型连接失败弹窗界面的确定按钮
+
+ class AivoiceMobileDataFailedStartView
+ {
+ public:
+ struct LabelConfig
+ {
+ int16_t left;
+ int16_t top;
+ int16_t width;
+ int16_t height;
+ int16_t fontSize;
+ int16_t lineHeigh;
+ uint16_t textId;
+ uint8_t lineBreakMode;
+ };
+ struct ButtonConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ const char *ViewId;
+ };
+
+ struct ImageConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ };
+
+ AivoiceMobileDataFailedStartView();
+ ~AivoiceMobileDataFailedStartView();
+ static AivoiceMobileDataFailedStartView *GetInstance(void);
+ UIScrollView *CreateAivoiceMobileDataFailedStartView(void);
+ void UpdateTitleTextId(int textId);
+
+ private:
+ void ClearAll(void);
+ UILabelExt *AivoiceMobileDataFailedStartLabelInit(LabelConfig &labelconfig);
+ UIButton *AivoiceMobileDataFailedStartButtonInit(ButtonConfig &buttonconfig);
+ UIImageView *AivoiceMobileDataFailedStartImageInit(ImageConfig &imageconfig);
+ bool CreateAivoiceMobileDataFailedStartLabel(void);
+ bool CreateAivoiceMobileDataFailedStartButton(void);
+ bool CreateAivoiceMobileDataFailedStartImage(void);
+ bool CreateAivoiceMobileDataFailedStartScrollView(void);
+ UIScrollView *scrollView{nullptr};
+ UILabelExt *title{nullptr};
+ UIImageView *attentionImage{nullptr};
+ UILabelExt *label[2]{nullptr};
+ UILabelExt *ensure{nullptr};
+ UIButton *ensureButton{nullptr};
+ };
+}
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-22 16:46:26
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2025-03-07 09:26:23
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AivoiceReturnResultTextView.h
+ */
+
+#ifndef AIVOICE_RETURN_RESULT_TEXT_VIEW_H
+#define AIVOICE_RETURN_RESULT_TEXT_VIEW_H
+
+#include "components/ui_scroll_view.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_button.h"
+#include "components/ui_image_view.h"
+#include "aivoice/include/AivoiceChatContentListAdapter.h"
+#include "aivoice/include/AivoiceChatContentListItemView.h"
+namespace OHOS
+{
+ static constexpr const char *AIVOICERETURNRESULTTEXT_RETURN_BUTTON_VIEW_ID = "AivoiceReturnResultTextReturnButton"; // 返回对话内容界面的返回按钮
+ static constexpr const char *AIVOICERETURNRESULTTEXT_CONTINUECHAT_BUTTON_VIEW_ID = "AivoiceReturnResultTextContinueChatButton"; // 返回对话内容界面的继续对话按钮
+
+ class AivoiceReturnResultTextView
+ {
+ public:
+ struct LabelConfig
+ {
+ int16_t left;
+ int16_t top;
+ int16_t width;
+ int16_t height;
+ int16_t fontSize;
+ int16_t lineHeight;
+ uint16_t textId;
+ uint8_t lineBreakMode;
+ };
+ struct ButtonConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ const char *ViewId;
+ };
+ struct ImageConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ const char *src;
+ };
+
+ AivoiceReturnResultTextView();
+ ~AivoiceReturnResultTextView();
+ static AivoiceReturnResultTextView *GetInstance(void);
+ UIScrollView *CreateAivoiceReturnResultTextView(void);
+ void AddChatContentToList(const ChatContentItem &item);
+ AivoiceChatContentListAdapter *GetAivoiceChatContentListAdapter(void);
+ UIList *GetChatContentList(void);
+ void UpdateTitleTextId(int textId);
+ void IsScrollChatContentList(bool isScroll);
+
+ private:
+ void ClearAll(void);
+ UILabelExt *AivoiceReturnResultTextLabelInit(LabelConfig &labelconfig);
+ UIButton *AivoiceReturnResultTextButtonInit(ButtonConfig &buttonconfig);
+ UIImageView *AivoiceReturnResultTextImageInit(ImageConfig &imageconfig);
+ bool CreateAivoiceReturnResultTextLabel(void);
+ bool CreateAivoiceReturnResultTextList(void);
+ bool CreateAivoiceReturnResultTextButton(void);
+ bool CreateAivoiceReturnResultTextScrollView(void);
+ UIScrollView *scrollView{nullptr};
+ UILabelExt *title{nullptr};
+
+ UIButton *returnButton{nullptr};
+
+ UIButton *continueChatButton{nullptr};
+ UILabelExt *continueChat{nullptr};
+
+ AivoiceChatContentListAdapter *chatContentListAdapter{nullptr};
+ UIList *chatContentList{nullptr};
+ };
+}
+#endif
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-22 16:46:26
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-09-06 18:02:48
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AivoiceThinkingView.h
+ */
+
+#ifndef AIVOICE_THINKING_VIEW_H
+#define AIVOICE_THINKING_VIEW_H
+
+#include "components/ui_scroll_view.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_button.h"
+#include "components/ui_image_view.h"
+#include "components/ui_image_animator.h"
+namespace OHOS
+{
+ static constexpr const char *CANCEL_THINKING_BUTTON_VIEW_ID = "CancelThinkingButton"; // 思考中界面取消按钮
+
+ static constexpr int16_t AIVOICE_THINKING_IMAGE_ANIMATOR_VIEW_X = 153;
+ static constexpr int16_t AIVOICE_THINKING_IMAGE_ANIMATOR_VIEW_Y = 136;
+ static constexpr int16_t AIVOICE_THINKING_IMAGE_ANIMATOR_VIEW_W = 160;
+ static constexpr int16_t AIVOICE_THINKING_IMAGE_ANIMATOR_VIEW_H = 160;
+ static constexpr int16_t AIVOICE_THINKING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES = 40; // 图片帧数
+ static constexpr int16_t AIVOICE_THINKING_IMAGE_ANIMATOR_DELAY = 70; // 图片更新间隔
+ static constexpr const char *AIVoiceThinkingImagePaths = "/user/res/AIVoice/AIVoiceThinking/";
+ class AivoiceThinkingView
+ {
+ public:
+ struct LabelConfig
+ {
+ int16_t left;
+ int16_t top;
+ int16_t width;
+ int16_t height;
+ int16_t fontSize;
+ int16_t lineHeigh;
+ uint16_t textId;
+ uint8_t lineBreakMode;
+ };
+ struct ButtonConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t w;
+ int16_t h;
+ const char *ViewId;
+ };
+
+ struct ImageAnimatorConfig
+ {
+ int16_t x;
+ int16_t y;
+ int16_t width;
+ int16_t height;
+ ImageAnimatorInfo *imageInfoArray;
+ const ImageInfo **pathsArray;
+ uint8_t numFrames;
+ int delay;
+ };
+
+ AivoiceThinkingView();
+ ~AivoiceThinkingView();
+ static AivoiceThinkingView *GetInstance(void);
+ UIScrollView *CreateAivoiceThinkingView(void);
+
+ private:
+ void ClearAll(void);
+ UILabelExt *AivoiceThinkingLabelInit(LabelConfig &labelconfig);
+ UIButton *AivoiceThinkingButtonInit(ButtonConfig &buttonconfig);
+ UIImageAnimatorView *AivoiceThinkingImageAnimatorInit(ImageAnimatorConfig &imageanimatorconfig);
+ bool CreateAivoiceThinkingLabel(void);
+ bool CreateAivoiceThinkingButton(void);
+ bool CreateAivoiceThinkingImageAnimator(void);
+ bool CreateAivoiceThinkingScrollView(void);
+ UIScrollView *scrollView{nullptr};
+ UILabelExt *title{nullptr};
+ UILabelExt *cancelThink{nullptr};
+ UIButton *cancelThinkButton{nullptr};
+ UIImageAnimatorView *AiVoiceThinkingImageAnimatorView{nullptr};
+ ImageAnimatorInfo AiVoiceThinkingImageInfo[AIVOICE_THINKING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES];
+ const ImageInfo **AiVoiceThinkingPathsArray{nullptr};
+ };
+}
+#endif
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-07-02 09:46:24
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-07-02 09:48:05
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/ChatContentItem.h
+ */
+#ifndef CHAT_CONTENT_ITEM_H
+#define CHAT_CONTENT_ITEM_H
+
+#include <iostream>
+#include "string"
+namespace OHOS
+{
+ typedef struct
+ {
+ int index;
+ std::string text;
+ bool isAiAnswer;
+ } ChatContentItem;
+}
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-07-29 16:01:34
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-07-30 15:10:06
+ * @FilePath: /xts_origin/FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/apikeys/ApiKeysDeleteView.h
+ */
+
+#ifndef APIKEYS_DELETE_VIEW_H
+#define APIKEYS_DELETE_VIEW_H
+
+#include "components/ui_scroll_view.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_button.h"
+
+namespace OHOS
+{
+ static constexpr const char *APIKEYS_DELETE_BUTTON_VIEWID = "apikeys_delete_button_viewid"; /*删除APIKeys*/
+ static constexpr const char *APIKEYS_CANCEL_DELETE_BUTTON_VIEWID = "apikeys_cancel_delete_button_viewid"; /*取消删除APIkeys*/
+ static constexpr const char *APIKEYS_DELETE_SCROLLVIEW_VIEWID = "apikeys_delete_scrollview_viewid";
+
+ class ApiKeysDeleteView
+ {
+ public:
+ struct LabelConfig
+ {
+ int16_t left;
+ int16_t top;
+ int16_t width;
+ int16_t height;
+ int16_t fontSize;
+ int16_t lineHeigh;
+ uint16_t textId;
+ uint8_t lineBreakMode;
+ };
+
+ ApiKeysDeleteView();
+ ~ApiKeysDeleteView();
+ UIScrollView *CreateApiKeysDeleteView(void);
+
+ private:
+ UILabelExt *ApiKeysDeleteViewLabelInit(LabelConfig &labelconfig);
+ bool CreateApiKeysDeleteViewLabel(void);
+ void ClearAll(void);
+ UIScrollView *ApiKeysDeleteScrollView{nullptr};
+ UILabelExt *ApiKeysDeleteTitleLabel{nullptr};
+ UILabelExt *ApiKeysDeleteNoteLabel{nullptr};
+ UIButton *ApiKeysDeleteButton{nullptr};
+ UIButton *ApiKeysCancelDeleteButton{nullptr};
+ UIView::OnClickListener *clickListener{nullptr};
+ UIView::OnDragListener *dragListener{nullptr};
+ };
+}
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-07-29 16:14:05
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-07-29 16:24:29
+ * @FilePath: /xts_origin/FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/apikeys/ApiKeysPresenter.h
+ */
+
+#ifndef AI_MODELS_PRESENTER_H
+#define AI_MODELS_PRESENTER_H
+
+#include "View.h"
+namespace OHOS
+{
+ class ApiKeysPresenter : public UIView::OnClickListener,
+ public UIView::OnDragListener
+ {
+ public:
+ ApiKeysPresenter();
+ virtual ~ApiKeysPresenter();
+ static ApiKeysPresenter *GetInstance();
+
+ private:
+ bool OnClick(UIView &view, const ClickEvent &event) override;
+ bool OnDrag(UIView &view, const DragEvent &event) override;
+ bool OnDragEnd(UIView &view, const DragEvent &event) override;
+
+ bool X_DRAG_FLAG{false};
+ };
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-07-29 16:00:52
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-07-30 09:53:04
+ * @FilePath: /xts_origin/FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/apikeys/NotNotSetApiKeysView.h
+ */
+
+#ifndef NOT_SET_APIKEYS_VIEW_H
+#define NOT_SET_APIKEYS_VIEW_H
+
+#include "components/ui_scroll_view.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_button.h"
+
+namespace OHOS
+{
+ static constexpr const char *NOTSETAPIKEYS_ENSURE_BUTTON_VIEWID = "notsetapikeys_ensure_button_viewid";
+ static constexpr const char *NOTSETAPIKEYS_SCROLLVIEW_VIEWID = "notsetapikeys_scrollview_viewid";
+
+ class NotSetApiKeysView
+ {
+ public:
+ struct LabelConfig
+ {
+ int16_t left;
+ int16_t top;
+ int16_t width;
+ int16_t height;
+ int16_t fontSize;
+ int16_t lineHeigh;
+ uint16_t textId;
+ uint8_t lineBreakMode;
+ };
+
+ NotSetApiKeysView();
+ ~NotSetApiKeysView();
+ UIScrollView *CreateNotSetApiKeysView(void);
+
+ private:
+ UILabelExt *NotSetApiKeysViewLabelInit(LabelConfig &labelconfig);
+ bool CreateNotSetApiKeysViewLabel(void);
+ void ClearAll(void);
+ UIScrollView *NotSetApiKeysScrollView{nullptr};
+ UILabelExt *NotSetApiKeysTitleLabel{nullptr};
+ UILabelExt *NotSetApiKeysNoteLabel[3]{nullptr};
+ UILabelExt *NotSetApiKeysEnsureLabel{nullptr};
+ UIButton *NotSetApiKeysEnsureButton{nullptr};
+ UIView::OnClickListener *clickListener{nullptr};
+ UIView::OnDragListener *dragListener{nullptr};
+ };
+}
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-07-29 16:00:31
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-07-29 18:22:38
+ * @FilePath: /xts_origin/FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/apikeys/SetApiKeysView.h
+ */
+
+#ifndef SET_APIKEYS_VIEW_H
+#define SET_APIKEYS_VIEW_H
+
+#include "components/ui_scroll_view.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_image_view.h"
+#include "components/ui_button.h"
+
+namespace OHOS
+{
+ static constexpr const char *SETAPIKEYS_DELETE_BUTTON_VIEWID = "setapikeys_delete_button_viewid";
+ static constexpr const char *SETAPIKEYS_SCROLLVIEW_VIEWID = "setapikeys_scrollview_viewid";
+
+ static constexpr const char *SETAPIKEYS_IMAGE_PATH = "/user/res/AIVoice/apikey.bin";
+ class SetApiKeysView
+ {
+ public:
+ struct LabelConfig
+ {
+ int16_t left;
+ int16_t top;
+ int16_t width;
+ int16_t height;
+ int16_t fontSize;
+ int16_t lineHeigh;
+ uint16_t textId;
+ uint8_t lineBreakMode;
+ };
+
+ SetApiKeysView();
+ ~SetApiKeysView();
+ UIScrollView *CreateSetApiKeysView(void);
+
+ private:
+ UILabelExt *SetApiKeysViewLabelInit(LabelConfig &labelconfig);
+ bool CreateSetApiKeysViewLabel(void);
+ void ClearAll(void);
+ UIScrollView *SetApiKeysScrollView{nullptr};
+ UILabelExt *SetApiKeysTitleLabel{nullptr};
+ UIImageView *SetApiKeysImage{nullptr};
+ UILabelExt *SetApiKeysNoteLabel[2]{nullptr};
+ UILabelExt *SetApiKeysDeleteLabel{nullptr};
+ UIButton *SetApiKeysDeleteButton{nullptr};
+ UIView::OnClickListener *clickListener{nullptr};
+ UIView::OnDragListener *dragListener{nullptr};
+ };
+}
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-05-07 11:25:58
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2025-03-03 15:10:17
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/AiVoice/src/AiVoiceBluetoothFailedStartView.cpp
+ */
+#include "aivoice/include/AiVoicePresenter.h"
+#include "aivoice/include/AiVoiceModel.h"
+#include "aivoice/include/AiVoiceBluetoothFailedStartView.h"
+#include "wearable_log.h"
+#include "ui_resource_string.h"
+#include <UiConfig.h>
+namespace OHOS
+{
+
+ static AiVoiceBluetoothFailedStartView *g_pAiVoiceBluetoothFailedStartView{nullptr};
+
+ AiVoiceBluetoothFailedStartView::AiVoiceBluetoothFailedStartView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceBluetoothFailedStartView::AiVoiceBluetoothFailedStartView");
+ g_pAiVoiceBluetoothFailedStartView = this;
+ }
+
+ AiVoiceBluetoothFailedStartView::~AiVoiceBluetoothFailedStartView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceBluetoothFailedStartView::~AiVoiceBluetoothFailedStartView");
+ ClearAll();
+ g_pAiVoiceBluetoothFailedStartView = nullptr;
+ }
+
+ AiVoiceBluetoothFailedStartView *AiVoiceBluetoothFailedStartView::GetInstance()
+ {
+ return g_pAiVoiceBluetoothFailedStartView;
+ }
+
+ void AiVoiceBluetoothFailedStartView::ClearAll(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceBluetoothFailedStartView::ClearAll");
+ if (scrollView != nullptr)
+ {
+ scrollView->RemoveAll();
+
+ if (title != nullptr)
+ {
+ delete title;
+ title = nullptr;
+ }
+
+ if (attentionImage != nullptr)
+ {
+ delete attentionImage;
+ attentionImage = nullptr;
+ }
+
+ for (int i = 0; i < (sizeof(label) / sizeof(label[0])); i++)
+ {
+ if (label[i] != nullptr)
+ {
+ delete label[i];
+ label[i];
+ }
+ }
+
+ if (ensure != nullptr)
+ {
+ delete ensure;
+ ensure = nullptr;
+ }
+
+ if (ensureButton != nullptr)
+ {
+ delete ensureButton;
+ ensureButton = nullptr;
+ }
+
+ delete scrollView;
+ scrollView = nullptr;
+ }
+ }
+
+ UILabelExt *AiVoiceBluetoothFailedStartView::AiVoiceBluetoothFailedStartLabelInit(LabelConfig &labelconfig)
+ {
+ UILabelExt *label = new UILabelExt();
+ if (label == nullptr)
+ {
+ return nullptr;
+ }
+ label->SetPosition(labelconfig.left, labelconfig.top, labelconfig.width, labelconfig.height);
+ label->SetStyle(STYLE_TEXT_FONT, labelconfig.fontSize);
+ label->SetStyle(STYLE_LINE_HEIGHT, labelconfig.lineHeigh);
+ //TOOD: 待优化
+ if(labelconfig.textId == STR_DEEPSEEK) {
+ label->SetText("DeepSeek");
+ } else
+ label->SetTextId(labelconfig.textId);
+ label->SetLineBreakMode(labelconfig.lineBreakMode);
+ label->SetRollSpeed(23);
+ label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize);
+ return label;
+ }
+
+ UIButton *AiVoiceBluetoothFailedStartView::AiVoiceBluetoothFailedStartButtonInit(ButtonConfig &buttonconfig)
+ {
+ UIButton *button = new UIButton();
+ if (button == nullptr)
+ {
+ return nullptr;
+ }
+ button->SetPosition(buttonconfig.x, buttonconfig.y, buttonconfig.w, buttonconfig.h);
+ button->SetViewId(buttonconfig.ViewId);
+ button->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919);
+ button->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+ button->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff383838, UIButton::PRESSED);
+
+ return button;
+ }
+
+ UIImageView *AiVoiceBluetoothFailedStartView::AiVoiceBluetoothFailedStartImageInit(ImageConfig &imageconfig)
+ {
+ UIImageView *Image = new UIImageView();
+ if (Image == nullptr)
+ {
+ return nullptr;
+ }
+ Image->SetPosition(imageconfig.x, imageconfig.y, imageconfig.w, imageconfig.h);
+ return Image;
+ }
+
+ bool AiVoiceBluetoothFailedStartView::CreateAiVoiceBluetoothFailedStartScrollView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceBluetoothFailedStartView::CreateAiVoiceBluetoothFailedStartScrollView");
+ scrollView = new UIScrollView();
+ if (scrollView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceBluetoothFailedStartView::scrollView new fail!");
+ return false;
+ }
+ scrollView->SetPosition(0, 0, 466, 466);
+ scrollView->SetTouchable(true);
+ scrollView->SetDraggable(true);
+ UIView::OnDragListener *dragListener = static_cast<UIView::OnDragListener *>(AiVoicePresenter::GetInstance());
+ if (dragListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceBluetoothFailedStartView::dragListener new fail!");
+ return false;
+ }
+ scrollView->SetOnDragListener(dragListener);
+ return true;
+ }
+
+ bool AiVoiceBluetoothFailedStartView::CreateAiVoiceBluetoothFailedStartLabel(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceBluetoothFailedStartView::CreateAiVoiceBluetoothFailedStartLabel");
+ LabelConfig labelconfig = {
+ .left = 83,
+ .top = 50,
+ .width = 300,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = AiVoiceModel::GetInstance().GetAiModelTextId(),
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ title = AiVoiceBluetoothFailedStartLabelInit(labelconfig);
+ if (title == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceBluetoothFailedStartView::title is nullptr!");
+ return false;
+ }
+ /* -------------------------------------------------------------------------- */
+ labelconfig.left = 53;
+ labelconfig.width = 360;
+ int textId[] = {STR_BOOT_FAILED, STR_PCY4GC_OR_AS}; /*启动失败,请检查4G或打开APP连接*/
+ for (int i = 0; i < sizeof(textId) / sizeof(textId[0]); i++)
+ {
+ labelconfig.top = 222 + i * 35;
+ labelconfig.textId = textId[i];
+ label[i] = AiVoiceBluetoothFailedStartLabelInit(labelconfig);
+ if (label[i] == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceBluetoothFailedStartView::label[%d] is nullptr!", i);
+ return false;
+ }
+ }
+ /* -------------------------------------------------------------------------- */
+ labelconfig = {
+ .left = 133,
+ .top = 368,
+ .width = 200,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = STR_OK,
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ ensure = AiVoiceBluetoothFailedStartLabelInit(labelconfig);
+ if (ensure == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceBluetoothFailedStartView::ensure is nullptr!");
+ return false;
+ }
+
+ return true;
+ }
+
+ bool AiVoiceBluetoothFailedStartView::CreateAiVoiceBluetoothFailedStartButton(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceBluetoothFailedStartView::CreateAiVoiceBluetoothFailedStartButton");
+ ButtonConfig buttonconfig = {
+ .x = 93,
+ .y = 340,
+ .w = 280,
+ .h = 90,
+ .ViewId = ALERT_APPBLUETOOTH_AND_4GNETWORK_ENSURE_BUTTON_VIEW_ID,
+ };
+ ensureButton = AiVoiceBluetoothFailedStartButtonInit(buttonconfig);
+ if (ensureButton == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ensureButton new fail!");
+ return false;
+ }
+ UIView::OnTouchListener *onReleaseListener = static_cast<UIView::OnTouchListener *>(AiVoicePresenter::GetInstance());
+ if (onReleaseListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceBluetoothFailedStartView::draglistener can not be nullptr!");
+ return false;
+ }
+ ensureButton->SetOnTouchListener(onReleaseListener);
+
+ return true;
+ }
+
+ bool AiVoiceBluetoothFailedStartView::CreateAiVoiceBluetoothFailedStartImage(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceBluetoothFailedStartView::CreateAiVoiceBluetoothFailedStartImage");
+ ImageConfig imageconfig = {
+ .x = 193,
+ .y = 120,
+ .w = 80,
+ .h = 80,
+ };
+ attentionImage = AiVoiceBluetoothFailedStartImageInit(imageconfig);
+ if (attentionImage == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "attentionImage new fail!");
+ return false;
+ }
+ attentionImage->SetStyle(STYLE_BORDER_RADIUS, 100);
+ attentionImage->SetSrc(PNG_ATTENTION_IMAGE);
+
+ return true;
+ }
+
+ UIScrollView *AiVoiceBluetoothFailedStartView::CreateAiVoiceBluetoothFailedStartView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceBluetoothFailedStartView::CreateAiVoiceBluetoothFailedStartView");
+ if (scrollView == nullptr)
+ {
+ if (!CreateAiVoiceBluetoothFailedStartScrollView() || !CreateAiVoiceBluetoothFailedStartLabel() ||
+ !CreateAiVoiceBluetoothFailedStartButton() || !CreateAiVoiceBluetoothFailedStartImage())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceBluetoothFailedStartView::CreateAiVoiceBluetoothFailedStartView fail!!");
+ return nullptr;
+ }
+ scrollView->Add(title);
+ scrollView->Add(attentionImage);
+ scrollView->Add(label[0]);
+ scrollView->Add(label[1]);
+ scrollView->Add(ensureButton);
+ scrollView->Add(ensure);
+ }
+ return scrollView;
+ }
+
+ void AiVoiceBluetoothFailedStartView::UpdateTitleTextId(int textId)
+ {
+ if (title)
+ {
+ if(textId == STR_DEEPSEEK)
+ {
+ title->SetText("DeepSeek");
+ }
+ else
+ {
+ title->SetTextId(textId);
+ title->ForceResetText();
+ }
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-08-03 11:10:08
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-11-05 11:08:54
+ * @FilePath: /xts_origin/FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceConnectingView.cpp
+ */
+#include "aivoice/include/AiVoiceConnectingView.h"
+#include "aivoice/include/AiVoicePresenter.h"
+#include "wearable_log.h"
+#include "ui_resource_string.h"
+#include "common/image_cache_manager.h"
+#include "uicomponents/UIComponents.h"
+#include "uiservice/include/ui_service.h"
+namespace OHOS
+{
+ static constexpr int16_t AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_X = 183;
+ static constexpr int16_t AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_Y = 153;
+ static constexpr int16_t AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_W = 100;
+ static constexpr int16_t AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_H = 120;
+ static constexpr int16_t AIVOICE_CONNECTING_IMAGE_ANIMATOR_DELAY = 50; // 图片更新间隔
+ static constexpr const char *AIVoiceListeningImagePaths = "/user/res/connect/";
+
+ static AiVoiceConnectingView *g_pAiVoiceConnecting{nullptr};
+ AiVoiceConnectingView::AiVoiceConnectingView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::AiVoiceConnectingView");
+ g_pAiVoiceConnecting = this;
+ }
+
+ AiVoiceConnectingView::~AiVoiceConnectingView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::~AiVoiceConnectingView");
+ ClearAll();
+ g_pAiVoiceConnecting = nullptr;
+ }
+
+ void AiVoiceConnectingView::ClearAll(void)
+ {
+ if (scrollView != nullptr)
+ {
+ scrollView->RemoveAll();
+ if (title)
+ {
+ delete title;
+ title = nullptr;
+ }
+ if (connectingAnimatorView)
+ {
+ connectingAnimatorView->Stop();
+ delete connectingAnimatorView;
+ connectingAnimatorView = nullptr;
+ FreeImageInfoArray(connectingPathsArray, AIVoiceListeningImagePaths, AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES);
+ }
+ if (cancelLabel)
+ {
+ delete cancelLabel;
+ cancelLabel = nullptr;
+ }
+ if (cancelButton != nullptr)
+ {
+ delete cancelButton;
+ cancelButton = nullptr;
+ }
+
+ delete scrollView;
+ scrollView = nullptr;
+ }
+ ScreenTurnOff();
+ }
+
+ AiVoiceConnectingView *AiVoiceConnectingView::GetInstance(void)
+ {
+ return g_pAiVoiceConnecting;
+ }
+
+ UILabelExt *AiVoiceConnectingView::AiVoiceConnectingViewLabelInit(LabelConfig &labelconfig)
+ {
+ UILabelExt *label = new UILabelExt();
+ if (label == nullptr)
+ {
+ return nullptr;
+ }
+ label->SetPosition(labelconfig.left, labelconfig.top, labelconfig.width, labelconfig.height);
+ label->SetStyle(STYLE_TEXT_FONT, labelconfig.fontSize);
+ label->SetStyle(STYLE_LINE_HEIGHT, labelconfig.lineHeigh);
+ label->SetTextId(labelconfig.textId);
+ label->SetLineBreakMode(labelconfig.lineBreakMode);
+ label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ label->SetRollSpeed(23);
+ label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize);
+ return label;
+ }
+
+ UIButton *AiVoiceConnectingView::AiVoiceConnectingViewButtonInit(ButtonConfig &buttonconfig)
+ {
+ UIButton *button = new UIButton();
+ if (button == nullptr)
+ {
+ return nullptr;
+ }
+ button->SetPosition(buttonconfig.x, buttonconfig.y, buttonconfig.w, buttonconfig.h);
+ button->SetViewId(buttonconfig.viewId);
+ button->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919);
+ button->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+ button->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff383838, UIButton::PRESSED);
+
+ return button;
+ }
+
+ UIImageAnimatorView *AiVoiceConnectingView::connectingImageAnimatorInit(ImageAnimatorConfig &imageanimatorconfig)
+ {
+ UIImageAnimatorView *animatorView = new UIImageAnimatorView();
+ if (animatorView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceListeningImageAnimatorView::AiVoiceListeningImageAnimatorView new fail");
+ return nullptr;
+ }
+
+ for (uint8_t i = 0; i < imageanimatorconfig.numFrames; i++)
+ {
+ imageanimatorconfig.imageInfoArray[i].imageInfo = (imageanimatorconfig.pathsArray[i]);
+ imageanimatorconfig.imageInfoArray[i].imageType = IMG_SRC_IMAGE_INFO;
+ // imageanimatorconfig.imageInfoArray[i].imagePath = (imageanimatorconfig.pathsArray[i]);
+ // imageanimatorconfig.imageInfoArray[i].imageType = IMG_SRC_FILE_PATH;
+ imageanimatorconfig.imageInfoArray[i].pos.x = imageanimatorconfig.x;
+ imageanimatorconfig.imageInfoArray[i].pos.y = imageanimatorconfig.y;
+ imageanimatorconfig.imageInfoArray[i].width = imageanimatorconfig.width;
+ imageanimatorconfig.imageInfoArray[i].height = imageanimatorconfig.height;
+ }
+
+ animatorView->SetPosition(imageanimatorconfig.x, imageanimatorconfig.y, imageanimatorconfig.width, imageanimatorconfig.height);
+ animatorView->SetImageAnimatorSrc(imageanimatorconfig.imageInfoArray, imageanimatorconfig.numFrames, imageanimatorconfig.delay);
+ animatorView->SetRepeat(true);
+ animatorView->SetSizeFixed(true);
+ // animatorView->SetAutoEnable(false);
+ // animatorView->SetResizeMode(UIImageAnimatorView::FILL);
+ animatorView->Start();
+
+ return animatorView;
+ }
+
+ bool AiVoiceConnectingView::CreateAiVoiceConnectingViewLabel(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::CreateAiVoiceConnectingViewLabel");
+ LabelConfig labelConfig = {
+ .left = 83,
+ .top = 50,
+ .width = 300,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = STR_CONNECTING,
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ if (title == nullptr)
+ {
+ title = AiVoiceConnectingViewLabelInit(labelConfig);
+ if (title == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "title new fail!");
+ return false;
+ }
+ }
+ /* -------------------------------------------------------------------------- */
+ labelConfig = {
+ .left = 133,
+ .top = 368,
+ .width = 200,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = STR_CANCEL,
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ if (cancelLabel == nullptr)
+ {
+ cancelLabel = AiVoiceConnectingViewLabelInit(labelConfig);
+ if (cancelLabel == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceBluetoothFailedStartView::cancelLabel is nullptr!");
+ return false;
+ }
+ cancelLabel->SetTextColor(Color::GetColorFromRGBA(0xfd, 0x52, 0x13, 0xff));
+ }
+
+ return true;
+ }
+
+ bool AiVoiceConnectingView::CreateAiVoiceConnectingViewButton(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::CreateAiVoiceConnectingViewButton");
+ ButtonConfig buttonconfig = {
+ .x = 93,
+ .y = 340,
+ .w = 280,
+ .h = 90,
+ .viewId = AIVOICECONNECTINGVIEW_CANCEL_BUTTON_VIEW_ID,
+ };
+ if (cancelButton == nullptr)
+ {
+ cancelButton = AiVoiceConnectingViewButtonInit(buttonconfig);
+ if (cancelButton == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "cancelButton new fail!");
+ return false;
+ }
+ }
+ UIView::OnTouchListener *touchListener = static_cast<UIView::OnTouchListener *>(AiVoicePresenter::GetInstance());
+ if (touchListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::touchListener can not be nullptr!");
+ return false;
+ }
+ cancelButton->SetOnTouchListener(touchListener);
+
+ return true;
+ }
+
+ bool AiVoiceConnectingView::CreateAivoiceConnectingImageAnimator(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::CreateAivoiceConnectingImageAnimator");
+ if (connectingPathsArray == nullptr)
+ {
+ connectingPathsArray = CreateImageInfoArray(AIVoiceListeningImagePaths, AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES);
+ if (connectingPathsArray == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::connectingPathsArray is nullptr!!");
+ return false;
+ }
+ }
+
+ ImageAnimatorConfig imageanimatorconfig = {
+ .x = AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_X,
+ .y = AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_Y,
+ .width = AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_W,
+ .height = AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_H,
+ .imageInfoArray = connectingImageInfo,
+ .pathsArray = connectingPathsArray,
+ .numFrames = AIVOICE_CONNECTING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES,
+ .delay = AIVOICE_CONNECTING_IMAGE_ANIMATOR_DELAY,
+ };
+ if (connectingAnimatorView == nullptr)
+ {
+ connectingAnimatorView = connectingImageAnimatorInit(imageanimatorconfig);
+ if (connectingAnimatorView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::connectingAnimatorView new fail");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ bool AiVoiceConnectingView::CreateAiVoiceConnectingScrollView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::CreateAiVoiceConnectingScrollView");
+ if (scrollView == nullptr)
+ {
+ scrollView = new UIScrollView();
+ if (scrollView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::scrollView new fail!");
+ return false;
+ }
+ }
+ UIView::OnDragListener *dragListener = static_cast<UIView::OnDragListener *>(AiVoicePresenter::GetInstance());
+ if (dragListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::dragListener new fail!");
+ return false;
+ }
+ scrollView->SetOnDragListener(dragListener);
+ scrollView->SetPosition(0, 0, 466, 466);
+ scrollView->SetTouchable(true);
+ scrollView->SetDraggable(true);
+
+ return true;
+ }
+
+ bool AiVoiceConnectingView::CreateAiVoiceConnectingScrollView(uint8_t type)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::CreateAiVoiceConnectingScrollView");
+ if (scrollView == nullptr)
+ {
+ scrollView = new UIScrollView();
+ if (scrollView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::scrollView new fail!");
+ return false;
+ }
+ }
+ scrollView->SetPosition(0, 0, 466, 466);
+ scrollView->SetTouchable(true);
+ scrollView->SetDraggable(true);
+
+ return true;
+ }
+
+ UIScrollView *AiVoiceConnectingView::CreateAiVoiceConnectingView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::CreateAiVoiceConnectingView");
+#if 0
+ if (!CreateAiVoiceConnectingScrollView() || !CreateAivoiceConnectingImageAnimator() || !CreateAiVoiceConnectingViewLabel() || !CreateAiVoiceConnectingViewButton())
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::CreateAiVoiceConnectingView fail!!");
+ return nullptr;
+ }
+ scrollView->Add(title);
+ scrollView->Add(connectingAnimatorView);
+ scrollView->Add(cancelButton);
+ scrollView->Add(cancelLabel);
+
+ return scrollView;
+#else
+ if (!CreateAiVoiceConnectingScrollView())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::CreateAiVoiceConnectingScrollView fail!!");
+ }
+ if (!CreateAivoiceConnectingImageAnimator())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::CreateAivoiceConnectingImageAnimator fail!!");
+ }
+ if (!CreateAiVoiceConnectingViewLabel())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::CreateAiVoiceConnectingViewLabel fail!!");
+ }
+ if (!CreateAiVoiceConnectingViewButton())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::CreateAiVoiceConnectingViewButton fail!!");
+ }
+
+#endif
+ if (scrollView == nullptr)
+ {
+ return nullptr;
+ }
+ else
+ {
+ if (title)
+ {
+ scrollView->Add(title);
+ }
+ if (connectingAnimatorView)
+ {
+ scrollView->Add(connectingAnimatorView);
+ }
+ if (cancelButton)
+ {
+ scrollView->Add(cancelButton);
+ }
+ if (cancelLabel)
+ {
+ scrollView->Add(cancelLabel);
+ }
+ return scrollView;
+ }
+ }
+
+ UIScrollView *AiVoiceConnectingView::CreateAiVoiceConnectingView(uint8_t type)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::CreateAiVoiceConnectingView");
+#if 0
+ if (!CreateAiVoiceConnectingScrollView(type) || !CreateAivoiceConnectingImageAnimator() || !CreateAiVoiceConnectingViewLabel())
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::CreateAiVoiceConnectingView fail!!");
+ return nullptr;
+ }
+ connectingAnimatorView->SetPosition(183, 183);
+ connectingAnimatorView->Invalidate();
+ ScreenTurnOn(30 * 1000); // 亮屏30s
+ scrollView->Add(connectingAnimatorView);
+#else
+ if (!CreateAiVoiceConnectingScrollView(type))
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::CreateAiVoiceConnectingScrollView fail!!");
+ }
+ if (!CreateAivoiceConnectingImageAnimator())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::CreateAivoiceConnectingImageAnimator fail!!");
+ }
+ if (!CreateAiVoiceConnectingViewLabel())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceConnectingView::CreateAiVoiceConnectingViewLabel fail!!");
+ }
+ if (scrollView == nullptr)
+ {
+ return nullptr;
+ }
+ else
+ {
+ if (connectingAnimatorView)
+ {
+ connectingAnimatorView->SetPosition(183, 183);
+ connectingAnimatorView->Invalidate();
+ scrollView->Add(connectingAnimatorView);
+ }
+ ScreenTurnOn(30 * 1000); // 亮屏30s
+ return scrollView;
+ }
+#endif
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-20 15:14:50
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2025-03-19 11:09:58
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceModel.cpp
+ */
+#include "aivoice/include/AiVoiceModel.h"
+#include "aivoice/include/AiVoicePresenter.h"
+#include "aivoice/include/AiVoiceView.h"
+#include "aivoice/include/AivoiceReturnResultTextView.h"
+#include "wearable_log.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cmsis_os2.h>
+#include <cmsis_os.h>
+#include <ohos_types.h>
+#include <service/graphic_service.h>
+#include <iostream>
+#include "uiservice/include/ui_service.h"
+#include <custom_utils.h>
+#ifdef SUPPORT_BLE_SERVICE
+#include <bleEvent.h>
+#include "bleService.h"
+#endif
+#include <unistd.h>
+#include "ConfigModel.h"
+#include "settings/include/SettingModel.h"
+#include <unistd.h>
+#include <sys/stat.h>
+#include <custom_save_runtime.h>
+namespace OHOS
+{
+ // 声明定时器变量
+ static osTimerId_t g_timer = nullptr;
+ static constexpr uint16_t THIRTY_TIME = 30 / 3;
+ static int Time = THIRTY_TIME;
+ static int AiModelConnectTimeout = 5;
+
+ AiVoiceModel::AiVoiceModel()
+ {
+ CreateDirectory("/user/userdata/AiRecording/");
+ }
+
+ AiVoiceModel::~AiVoiceModel() {}
+
+ AiVoiceModel &AiVoiceModel::GetInstance()
+ {
+ static AiVoiceModel instance;
+ return instance;
+ }
+
+ bool AiVoiceModel::CreateDirectory(const char *path)
+ {
+ if (access(path, F_OK) == -1)
+ { // 如果路径不存在
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Directory %s not exist, creating directory\n", path);
+ if (mkdir(path, 0777) != 0)
+ { // 尝试创建目录,如果创建失败
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Create directory %s failed\n", path);
+ return false;
+ }
+ }
+ else
+ { // 如果路径存在
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Directory %s already exists\n", path);
+ }
+ return true;
+ }
+
+ // 跳转到返回结果界面
+ bool AiVoiceModel::ChangeToReturnResultTextView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::ChangeToReturnResultTextView");
+ AiVoicePresenter *Aipresenter_ = AiVoicePresenter::GetInstance();
+ if (Aipresenter_ == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::ChangeToReturnResultTextView fail!!");
+ return false;
+ }
+ Aipresenter_->JumpToReturnResultTextView();
+ entryTextViewState = false;
+ return true;
+ }
+
+ /*跳转到AI聆听界面界面*/
+ bool AiVoiceModel::ChangeToAIVoiceListeningView(bool value)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::ChangeToAIVoiceListeningView");
+ AiVoicePresenter *Aipresenter_ = AiVoicePresenter::GetInstance();
+ if (Aipresenter_ == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::ChangeToAIVoiceListeningView fail!!");
+ return false;
+ }
+ Aipresenter_->ChangeToAIVoiceListeningView(value);
+ return true;
+ }
+
+ // 切换到AI回应错误界面
+ bool AiVoiceModel::ChangeToAIVoiceConnectTimeoutView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::ChangeToAIVoiceConnectTimeoutView");
+ AiVoicePresenter *Aipresenter_ = AiVoicePresenter::GetInstance();
+ if (Aipresenter_ == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::GetInstance() fail!!");
+ return false;
+ }
+ Aipresenter_->ChangeToAIVoiceConnectTimeoutView();
+ return true;
+ }
+
+ // 功能键切换模型
+ void AiVoiceModel::FunctionKeyOnClickToChangeAIModel(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::FunctionKeyOnClickToChangeAIModel");
+ AiVoicePresenter *Aipresenter_ = AiVoicePresenter::GetInstance();
+ if (Aipresenter_ == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::FunctionKeyOnClickToChangeAIModel fail!!");
+ return;
+ }
+ Aipresenter_->FunctionKeyOnClickToChangeAIModel();
+ return;
+ }
+
+ /*获取API Keys是否可用*/
+ bool AiVoiceModel::IsExistOpenAIAPIKeys()
+ {
+ bool flag;
+ if (ConfigModel::GetInstance()->GetOpenAIAPIKeys() == "-1")
+ {
+ flag = false;
+ }
+ else
+ {
+ flag = true;
+ }
+ return flag;
+ }
+
+ /*删除本地的API Keys*/
+ void AiVoiceModel::DeleteLocalOpenAIAPIKeys()
+ {
+ ConfigModel::GetInstance()->SetOpenAIAPIKeys("-1");
+ }
+
+ // 获取APP蓝牙是否已连接
+ bool AiVoiceModel::GetAPPBluetoothIsConnect(void)
+ {
+ // return SettingModel::GetInstance().GetPhoneConnectStatus();
+
+ #ifdef SUPPORT_BLE_SERVICE
+ return get_ble_connect();
+ #else
+ return false;
+ #endif
+ }
+
+ // 获取4G网络是否正常
+ bool AiVoiceModel::GetMobileDataIsOpen(void)
+ {
+ return false;
+ }
+
+ /*查询用户选择的AI模型是否已经连接*/
+ void AiVoiceModel::QuerySelectedAiModelIsConnect()
+ {
+ #ifdef SUPPORT_BLE_SERVICE
+ auto it = selectAiModelToTextId.find(GetSelectAiModel());
+ if (it != selectAiModelToTextId.end())
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[QuerySelectedAiModelIsConnect] SelectAiModel = %d", it->second.second);
+ inquire_AI_is_ready(it->second.second);
+ }
+ #endif
+ }
+
+ // 获取当前正在使用的AI模型
+ uint8_t AiVoiceModel::GetCurUsingAiModelType(void){
+
+ auto it = selectAiModelToTextId.find(GetSelectAiModel());
+ if (it != selectAiModelToTextId.end())
+ {
+ return it->second.second;
+ }
+ return 0;
+ }
+
+ /*取消当前AI对话*/
+ void AiVoiceModel::CancelCurAIChat(void)
+ {
+ // cancel_AI_cur_chat(); //线程发送取消当前对话
+ #ifdef SUPPORT_BLE_SERVICE
+ cancel_AI_cur_chat_();// 直接发送取消当前对话
+ #endif
+ }
+
+ int AiVoiceModel::GetAIResponseType(void)
+ {
+ return AIResponseType;
+ }
+
+ std::string AiVoiceModel::GetErrnote(void)
+ {
+ return errnote;
+ }
+
+ void AiVoiceModel::SetErrnote(std::string str)
+ {
+ errnote = str;
+ }
+
+ /*设置当前哪个子视图是可见的*/
+ void AiVoiceModel::SetCurView(int16_t viewNum)
+ {
+ curView = viewNum;
+ }
+
+ /*获取当前哪个子视图是可见的*/
+ int AiVoiceModel::GetCurView(void)
+ {
+ return curView;
+ }
+
+ /*列表数量*/
+ uint8_t AiVoiceModel::GetChatContentListCount(void)
+ {
+ return ChatContentListCount;
+ }
+
+ /*添加聊天内容项到数组*/
+ bool AiVoiceModel::AddChatContentToItemArray(const ChatContentItem &item)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChatContentListCount = %d", ChatContentListCount);
+ // 检查 ChatContentListCount 是否超出范围
+ if (ChatContentListCount >= MaxChatContentListCount)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ChatContentListCount out of bounds!!");
+ return false;
+ }
+
+ chatTtems[ChatContentListCount] = item;
+ ChatContentListCount++;
+
+ return true;
+ }
+
+ /*添加用户问题项*/
+ bool AiVoiceModel::AddUserQuestionToChatItems()
+ {
+ ChatContentItem UserQuestionStrItem;
+ UserQuestionStrItem.index = GetChatContentListCount();
+ UserQuestionStrItem.text = GetUserQuestionStr();
+ UserQuestionStrItem.isAiAnswer = false;
+ return AddChatContentToItemArray(UserQuestionStrItem);
+ }
+
+ /*添加AI回答项*/
+ bool AiVoiceModel::AddAiAnswerToChatItems()
+ {
+ ChatContentItem AiAnswerStrItem;
+ AiAnswerStrItem.index = GetChatContentListCount();
+ AiAnswerStrItem.text = GetAiAnswerStr();
+ AiAnswerStrItem.isAiAnswer = true;
+ return AddChatContentToItemArray(AiAnswerStrItem);
+ }
+
+ /*初始化历史对话数据*/
+ bool AiVoiceModel::InitchatContentItems(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::InitchatContentItems");
+
+ // 获取单例对象
+ AivoiceReturnResultTextView *p_AivoiceReturnResultTextView = AivoiceReturnResultTextView::GetInstance();
+ if (p_AivoiceReturnResultTextView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::GetInstance fail!!");
+ return false;
+ }
+
+ // 添加用户问题项到数组
+ if (!AddUserQuestionToChatItems())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AddUserQuestionToChatItems fail!!");
+ return false;
+ }
+
+ // 添加AI回答项到数组
+ if (!AddAiAnswerToChatItems())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AddAiAnswerToChatItems fail!!");
+ return false;
+ }
+
+ // 将聊天内容添加到显示列表中
+ for (uint8_t i = 0; i < ChatContentListCount; i++)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "chatTtems[%d]", i);
+ p_AivoiceReturnResultTextView->AddChatContentToList(chatTtems[i]);
+ }
+
+ // 更新显示列表
+ auto chatContentListAdapter = p_AivoiceReturnResultTextView->GetAivoiceChatContentListAdapter();
+ auto chatContentList = p_AivoiceReturnResultTextView->GetChatContentList();
+ if (chatContentListAdapter != nullptr && chatContentList != nullptr)
+ {
+ chatContentList->SetAdapter(chatContentListAdapter);
+ // chatContentList->RefreshList();
+ }
+ else
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Chat content list or adapter is nullptr!!");
+ return false;
+ }
+
+ return true;
+ }
+
+ // 函数定义:移除列表的最后两项或清空列表
+ bool AiVoiceModel::RemoveLastTwoItemsOrClear()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::RemoveLastTwoItemsOrClear");
+ AivoiceReturnResultTextView *p_AivoiceReturnResultTextView = AivoiceReturnResultTextView::GetInstance();
+ if (p_AivoiceReturnResultTextView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::GetInstance fail!!");
+ return false;
+ }
+ // 获取适配器
+ AivoiceChatContentListAdapter *adapter = p_AivoiceReturnResultTextView->GetAivoiceChatContentListAdapter();
+ if (adapter != nullptr)
+ {
+ // 获取列表的大小
+ size_t listSize = adapter->GetChatContentItem().size();
+
+ // 移除最后两项或清空列表
+ if (listSize >= 2)
+ {
+ auto it = adapter->GetChatContentItem().end();
+ std::advance(it, -2); // 移动迭代器到倒数第二项的位置
+ adapter->GetChatContentItem().erase(it, adapter->GetChatContentItem().end());
+ }
+ else if (listSize == 1)
+ {
+ // 如果列表只有一项,直接清空
+ adapter->GetChatContentItem().clear();
+ }
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "listSize = %d", listSize);
+ ChatContentListCount -= (listSize < 2 ? listSize : 2);
+ }
+ return true;
+ }
+
+ /* 更新用户问题字符串 */
+ bool AiVoiceModel::UpdateUserQuestionStr()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::UpdateUserQuestionStr");
+
+ if(!RemoveLastTwoItemsOrClear())
+ {
+ return false;
+ }
+
+ if (!AddUserQuestionToChatItems())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AddUserQuestionToChatItems fail!!");
+ return false;
+ }
+
+ // 更新显示列表
+ AivoiceReturnResultTextView *p_AivoiceReturnResultTextView = AivoiceReturnResultTextView::GetInstance();
+ if (!p_AivoiceReturnResultTextView)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::GetInstance fail!!");
+ return false;
+ }
+
+ AivoiceChatContentListAdapter *adapter = static_cast<AivoiceChatContentListAdapter *>(p_AivoiceReturnResultTextView->GetAivoiceChatContentListAdapter());
+ if (adapter)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "GetChatContentListCount() - 1 = %d,line =%d", GetChatContentListCount() - 1, __LINE__);
+ adapter->GetChatContentItem().push_back(chatTtems[GetChatContentListCount() - 1]);
+ p_AivoiceReturnResultTextView->GetChatContentList()->RefreshList();
+ }
+ else
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Chat content adapter is nullptr!!");
+ return false;
+ }
+
+ return true;
+ }
+
+ /*更新Ai答案字符串*/
+ bool AiVoiceModel::UpdateAiAnswerStr()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::UpdateAiAnswerStr");
+ #if 0
+ AiVoiceView *view_ = AiVoiceView::GetInstance();
+ if(view_!= nullptr )
+ {
+ if(view_->GetAiVoiceScrollView(AIVOICE_RETURN_RESULT_TEXT_VIEWID) && !view_->GetAiVoiceScrollView(AIVOICE_RETURN_RESULT_TEXT_VIEWID)->IsVisible())
+ {
+ return false;
+ }
+ else
+ {
+ if(!GetIsClickable())
+ {
+ SetIsClickable(true);
+ }
+ }
+ }
+ #endif
+
+ int index = GetChatContentListCount() - 1;
+ if (index < 0 || index >= MaxChatContentListCount)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid index: %d", index);
+ return false;
+ }
+
+ if (chatTtems[index].isAiAnswer) // 处理ai1的多段回答
+ {
+ ChatContentListCount--;
+ }
+
+ if (!AddAiAnswerToChatItems())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AddAiAnswerToChatItems fail!!");
+ return false;
+ }
+
+ // 更新显示列表
+ AivoiceReturnResultTextView *p_AivoiceReturnResultTextView = AivoiceReturnResultTextView::GetInstance();
+ if (!p_AivoiceReturnResultTextView)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::GetInstance fail!!");
+ return false;
+ }
+
+ AivoiceChatContentListAdapter *adapter = static_cast<AivoiceChatContentListAdapter *>(p_AivoiceReturnResultTextView->GetAivoiceChatContentListAdapter());
+ if (adapter != nullptr && !adapter->GetChatContentItem().empty())
+ {
+ // 如果最后一条是 AI 回答,则移除
+ if (adapter->GetChatContentItem().back().isAiAnswer)
+ {
+ adapter->GetChatContentItem().pop_back();
+ }
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "GetChatContentListCount() - 1 = %d,line = %d", GetChatContentListCount() - 1, __LINE__);
+ // 将更新后的 AI 回答内容添加到列表
+ adapter->GetChatContentItem().push_back(chatTtems[GetChatContentListCount() - 1]);
+ if (AiVoicePresenter::GetInstance())
+ AiVoicePresenter::GetInstance()->calculateChatContentItemViewHeight(chatTtems[GetChatContentListCount() - 1].text, true);
+ p_AivoiceReturnResultTextView->GetChatContentList()->RefreshList();
+ }
+ else
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Chat content adapter is nullptr!!");
+ return false;
+ }
+
+ return true;
+ }
+
+ void AiVoiceModel::SetIsClickable(bool value)
+ {
+ isClickable = value;
+ }
+
+ bool AiVoiceModel::GetIsClickable(void)
+ {
+ return isClickable;
+ }
+
+ void AiVoiceModel::SetIsLimitDisplayed(bool value)
+ {
+ isLimitDisplayed = value;
+ }
+ bool AiVoiceModel::GetIsLimitDisplayed(void)
+ {
+ return isLimitDisplayed;
+ }
+
+ /*获取用户问题的字符串*/
+ std::string AiVoiceModel::GetUserQuestionStr(void)
+ {
+ // userQuestionStr = "写一篇100字文章";
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "GetUserQuestionStr:%s\n", userQuestionStr.c_str());
+ return userQuestionStr;
+ }
+
+ /*设置用户问题的字符串*/
+ void AiVoiceModel::SetUserQuestionStr(std::string str)
+ {
+ if (!entryTextViewState)
+ {
+ #ifdef SUPPORT_BLE_SERVICE
+ //SendMsgToUIService(UI_AI_JUMP_TO_RESULT_VIEW, 0, nullptr, 0);
+ #endif
+ entryTextViewState = true; // 进入返回结果界面的标志 避免重复发消息
+ usleep(50000); // 延时等待创建完成,0.05秒
+ }
+ /* -------------------------------------------------------------------------- */
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "传入的问题:%s",str.c_str());
+ userQuestionStr = str;
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "拼接的问题:%s",userQuestionStr.c_str());
+ /* -------------------------------------------------------------------------- */
+ #ifdef SUPPORT_BLE_SERVICE
+ //SendMsgToUIService(UI_UPDATE_USER_QUESTION_STR, 0, nullptr, 0);
+ #endif
+ }
+
+ /*获取Ai回答的字符串*/
+ std::string AiVoiceModel::GetAiAnswerStr(void)
+ {
+ // aiAnswerStr = "春风化雨,时光荏苒。百年之内,生命如白驹过隙,转瞬即逝。唯有心存善念,用爱化解芥蒂,用智慧建构未来,才是人生的真正意义。让我们携手共进,用每一分时光去关爱他人,用每一滴汗水去创造奇迹,用每一个眼神去传递温暖。让这个世界因我们的存在而变得更加美好。生命短暂,但只要我们怀着虔诚的心,坚韧前行,我们就一定能在有限的时光里留下无限的可能。";
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "GetAiAnswerStr:%s", aiAnswerStr.c_str());
+ return aiAnswerStr;
+ }
+
+ /*设置Ai回答的字符串*/
+ void AiVoiceModel::SetAiAnswerStrStr(std::string str)
+ {
+ aiAnswerStr += str;
+ //SendMsgToUIService(UI_UPDATE_AI_ANSWER_STR, 0, nullptr, 0);
+ }
+
+ void AiVoiceModel::SetAiAnswerStrStr(std::string str, uint8_t type)
+ {
+ AIResponseType = type;
+ errnote = str;
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AIResponseType = %d,errnote = %s\n", AIResponseType, errnote.c_str());
+ //如果是:AI录音解析错误或AI 回应错误 ,或者重传多次录音数据->跳转AI回应错误界面
+ if (AIResponseType == AiVoiceModel::AI_RECORDING_PARSING_ERROR || AIResponseType == AiVoiceModel::AI_RESPONSE_ERROR
+ || AIResponseType == AiVoiceModel::AI_BLE_ERROR)
+ {
+ //SendMsgToUIService(UI_AI_JUMP_TO_RESPONDERR_VIEW, 0, (void *)errnote.c_str(), errnote.length());
+ return;
+ }
+ else if (AiVoiceModel::AI_RESPONSE_END) // 如果是AI 回应结束
+ {
+ if (errnote.empty()) // 如果没有回应数据
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::GetErrnote is empty!!");
+ AiVoiceModel::GetInstance().SetErrnote("响应内容为空");
+ std::string str = AiVoiceModel::GetInstance().GetErrnote();
+ //SendMsgToUIService(UI_AI_JUMP_TO_RESPONDERR_VIEW, 0, (void *)str.c_str(), str.length());
+ return;
+ }
+ }
+ AiVoiceView *view_ = AiVoiceView::GetInstance();
+ if(view_!= nullptr )
+ {
+ if(view_->GetAiVoiceScrollView(AIVOICE_RETURN_RESULT_TEXT_VIEWID) && view_->GetAiVoiceScrollView(AIVOICE_RETURN_RESULT_TEXT_VIEWID)->IsVisible())
+ {
+ if(!OHOS::AiVoiceModel::GetInstance().GetIsLimitDisplayed()) //如果ai答案没有显示到极限了,就更新ai答案字符串
+ {
+ aiAnswerStr += str;
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "接受字的符串:%s", aiAnswerStr.c_str());
+ //SendMsgToUIService(UI_UPDATE_AI_ANSWER_STR, 0, nullptr, 0);
+ }
+ }
+ }
+ }
+
+ /*清空上次用户问题和Ai回答字符串*/
+ void AiVoiceModel::ClearQuestionAndAiAnswerStr(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "清空上次用户问题和Ai回答字符串");
+ userQuestionStr = "";
+ aiAnswerStr = "";
+ }
+
+ /*获取AI音频路径*/
+ std::string AiVoiceModel::GetAIAudioPath(void)
+ {
+ return AIAIAudioPath;
+ }
+
+#ifdef __cplusplus
+ extern "C"
+ {
+#endif
+ int32_t AudioCaptureSample(int32_t argc, const char *argv[]);
+ int32_t streamingRecordAndSend_AI(int type);
+ #define IS_SUPPORT_REALTIME_RECORD_SEND_AI 1 //是否支持实时发送录音数据
+#ifdef __cplusplus
+ };
+#endif
+
+ // 开始聆听并录取用户问题
+ void AiVoiceModel::StartListenAndRecordingUserQuestion(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "聆听用户问题并发送录音数据");
+ AiVoiceView *view_ = AiVoiceView::GetInstance();
+ if (view_ == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::GetInstance fail!!");
+ return;
+ }
+ if ((view_->GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID) != nullptr) &&
+ (view_->GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID)->IsVisible()))
+ {
+#if IS_SUPPORT_REALTIME_RECORD_SEND_AI
+ int type = GetCurUsingAiModelType();
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "type = %d", type);
+ #ifdef SUPPORT_BLE_SERVICE
+ streamingRecordAndSend_AI(type);//实时发送录音数据
+ #endif
+#else
+ std::string audioPath = AiVoiceModel::GetInstance().GetAIAudioPath();
+ if (uapi_delete_files(audioPath.c_str())) // 先删除文件
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "uapi_delete_files,%s", audioPath.c_str());
+ }
+ else
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "uapi_delete_files fail!!");
+ }
+#if CURRENT_AIAUDIO_TYPE == AIAUDIO_TYPE_PCM
+ const char *defaultArgs[6] = {"01", "pcm", "16000", "1", "16", audioPath.c_str()};
+#elif CURRENT_AIAUDIO_TYPE == AIAUDIO_TYPE_SBC
+ const char *defaultArgs[6] = {"01", "sbc", "16000", "1", "16", audioPath.c_str()};
+#elif CURRENT_AIAUDIO_TYPE == AIAUDIO_TYPE_MSBC
+ const char *defaultArgs[6] = {"01", "msbc", "16000", "1", "16", audioPath.c_str()};
+#endif
+ uapi_save_runtime_log(RUNTIME_LOG_RECORD_START_AI);//TOOD*
+ AudioCaptureSample(6, (const char **)defaultArgs);
+#endif
+ }
+ return;
+ }
+
+ // 停止聆听用户问题
+ void AiVoiceModel::StopListenAndRecordingUserQuestion(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "停止录音");
+ int32_t argc = 1;
+ uint8_t *argv = (uint8_t *)"stop";
+ AudioCaptureSample(argc, (const char **)&argv);
+ uapi_save_runtime_log(RUNTIME_LOG_RECORD_STOP_AI);//TOOD*
+ return;
+ }
+
+ /*检查录音文件是否存在并发送语音准备操作*/
+ void AiVoiceModel::CheckFileAndSendAIIsReady(void)
+ {
+ #ifdef SUPPORT_BLE_SERVICE
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::CheckFileAndSendAIIsReady");
+ const std::string &filePath = AIAIAudioPath;
+ FILE *file = fopen(filePath.c_str(), "r");
+ if (file != nullptr)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "File already exists: %s", filePath.c_str());
+
+ fseek(file, 0, SEEK_END);
+ long size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+ if (size != 0)
+ {
+ auto it = selectAiModelToTextId.find(GetSelectAiModel());
+ if (it != selectAiModelToTextId.end())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "filesize = %ld,SelectAiModel = %d", size, it->second.second);
+ if(get_ble_interval() >= BLE_CONNECT_INTERVAL_SLOW)
+ {
+ uapi_ble_connect_param_update(BLE_CONNECT_INTERVAL_HIGH);
+ }
+ send_AI_is_ready(it->second.second);
+ }
+ else
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetSelectAiModel fail!!", size, it->second.second);
+ }
+
+ ClearQuestionAndAiAnswerStr(); // 清空上次用户问题和Ai回答字符串
+ }
+ fclose(file);
+ }
+ else
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "File does not exist: %s", filePath.c_str());
+ // Handle the case where the file doesn't exist, if needed
+ }
+ #endif
+ }
+
+ void AiVoiceModel::sendAIIsReady()
+ {
+ #ifdef SUPPORT_BLE_SERVICE
+ auto it = selectAiModelToTextId.find(GetSelectAiModel());
+ if (it != selectAiModelToTextId.end())
+ {
+ // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "filesize = %ld,SelectAiModel = %d", size, it->second.second);
+ if(get_ble_interval() >= BLE_CONNECT_INTERVAL_SLOW)
+ {
+ uapi_ble_connect_param_update(BLE_CONNECT_INTERVAL_HIGH);
+ }
+ send_AI_is_ready(it->second.second);
+ }
+ #endif
+ }
+
+ void AiVoiceModel::StatusResume(void)
+ {
+ Time = THIRTY_TIME;
+ AiModelConnectTimeout = 5;
+ AiVoiceConnectStatus = false;
+
+ for (int i = 0; i < ChatContentListCount; i++)
+ {
+ chatTtems[i].index = 0;
+ chatTtems[i].text = "";
+ chatTtems[i].isAiAnswer = false;
+ }
+ ChatContentListCount = 0;
+ entryTextViewState = false;
+ isClickable = false;
+ isLimitDisplayed = false;
+ ClearQuestionAndAiAnswerStr();
+ StopListenAndRecordingUserQuestion();
+ }
+
+ /* -------------------------------------------------------------------------- */
+ /*定时器到期时的处理*/
+ static void AIVoice_TimerCallbackProc(int data)
+ {
+ // 等待AI思考完成的定时器
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AIVoice_TimerCallbackProc,Time = %d", Time);
+ if (Time < 0) // 如果思考时间超时30s,进入连接超时界面
+ {
+ AiVoiceModel::GetInstance().AIVoice_StopTimer();
+ AiVoiceModel::GetInstance().SetErrnote("连接超时,请重新开始对话");
+ std::string str = AiVoiceModel::GetInstance().GetErrnote();
+ //SendMsgToUIService(UI_AI_JUMP_TO_RESPONDERR_VIEW, 0, (void *)str.c_str(), str.length());
+ }
+ else
+ {
+ #ifdef SUPPORT_BLE_SERVICE
+ // 4g中途断连待扩展
+ // 蓝牙的连接状态判断,如果AI思考过程中途断连,直接弹窗提示,不在硬等
+ if (get_ble_connect() == false)
+ {
+ AiVoiceModel::GetInstance().SetErrnote("手机蓝牙已断开");
+ std::string str = AiVoiceModel::GetInstance().GetErrnote();
+ SendMsgToUIService(UI_AI_JUMP_TO_RESPONDERR_VIEW, 0, (void *)str.c_str(), str.length());
+ }
+ #endif
+ }
+ return;
+ }
+
+ /*
+ * @brief 回调函数
+ */
+ static void AIVoice_TimerCallback(int data)
+ {
+ Time -= 1;
+ GraphicService::GetInstance()->PostGraphicEvent(std::bind(AIVoice_TimerCallbackProc, data));
+ }
+
+ /*
+ * @brief 开启定时器函数
+ * @param interval 时间间隔,单位ms
+ */
+ void AiVoiceModel::AIVoice_StartTimer(uint32_t interval)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::AIVoice_StartTimer");
+ /* -------------------------- 1.检查定时器是否已经存在,如果存在则返回 ------------------------- */
+ if (g_timer != nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer already exists!!");
+ return;
+ }
+
+ /* --------------------------------- 2.创建定时器 -------------------------------- */
+ g_timer = osTimerNew((osTimerFunc_t)AIVoice_TimerCallback, osTimerPeriodic, nullptr, nullptr);
+ // 检查定时器创建是否成功
+ if (g_timer == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer create failed!!");
+ return;
+ }
+
+ /* ----------------------------- 3.将毫秒转换为系统时钟节拍数 ---------------------------- */
+ int tick = osMs2Tick(interval);
+
+ /* --------------------------------- 4.启动定时器 -------------------------------- */
+ osStatus_t ret = osTimerStart(g_timer, tick);
+ /* -------------------- 5.检查定时器启动是否成功,如果启动失败,删除定时器并置为 nullptr -------------------- */
+ if (ret != osOK)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
+ if (g_timer != nullptr)
+ {
+ ret = osTimerDelete(g_timer);
+ }
+ g_timer = nullptr;
+ return;
+ }
+ }
+
+ /*
+ * @brief 停止定时器
+ */
+ void AiVoiceModel::AIVoice_StopTimer(void)
+ {
+ // 检查定时器是否存在
+ if (g_timer != nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::AIVoice_StopTimer");
+ osTimerStop(g_timer);
+ // 删除定时器并置为 nullptr
+ osStatus_t ret = osTimerDelete(g_timer);
+ if (ret != osOK)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
+ }
+ g_timer = nullptr;
+ Time = THIRTY_TIME;
+ AiModelConnectTimeout = 5;
+ }
+ }
+
+ // 声明定时器变量
+ static osTimerId_t g_screen60s_timer = nullptr;
+ static int8_t SCREEN_60S_TIME = 60; // 60s
+
+ static void ai_start_screen60s_timer_callbackProc(int data)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::ai_start_screen60s_timer_callbackProc,time = %d", SCREEN_60S_TIME);
+ SCREEN_60S_TIME -= 30;
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::ai_start_screen60s_timer_callbackProc,time = %d", SCREEN_60S_TIME);
+ if (SCREEN_60S_TIME <= 0)
+ {
+ // 60s后息屏停止定时
+ AiVoiceModel::GetInstance().ai_stop_screen60s_timer();
+ // 取消常亮屏
+ ScreenAlwaysOnCtr(CANCEL_SCREEN_ALWAYS_ON);
+ }
+ }
+ static void ai_start_screen60s_timer_callback(int data)
+ {
+ // GraphicService::GetInstance()->PostGraphicEvent(std::bind(ai_start_screen60s_timer_callbackProc, data));
+ ai_start_screen60s_timer_callbackProc(data);
+ }
+ void AiVoiceModel::ai_start_screen60s_timer(uint32_t interval)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::ai_start_screen60s_timer");
+ /* -------------------------- 1.检查定时器是否已经存在,如果存在则返回 ------------------------- */
+ if (g_screen60s_timer != nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer already exists!!");
+ return;
+ }
+ /* --------------------------------- 2.创建定时器 -------------------------------- */
+ g_screen60s_timer = osTimerNew((osTimerFunc_t)ai_start_screen60s_timer_callback, osTimerPeriodic, nullptr, nullptr);
+ // 检查定时器创建是否成功
+ if (g_screen60s_timer == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer create failed!!");
+ return;
+ }
+ /* ----------------------------- 3.将毫秒转换为系统时钟节拍数 ---------------------------- */
+ int tick = osMs2Tick(interval);
+ /* --------------------------------- 4.启动定时器 -------------------------------- */
+ osStatus_t ret = osTimerStart(g_screen60s_timer, tick);
+ /* -------------------- 5.检查定时器启动是否成功,如果启动失败,删除定时器并置为 nullptr -------------------- */
+ if (ret != osOK)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
+ if (g_screen60s_timer != nullptr)
+ {
+ ret = osTimerDelete(g_screen60s_timer);
+ }
+ g_screen60s_timer = nullptr;
+ return;
+ }
+ }
+ void AiVoiceModel::ai_stop_screen60s_timer(void)
+ {
+ // 检查定时器是否存在
+ if (g_screen60s_timer != nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::ai_stop_screen60s_timer");
+ osTimerStop(g_screen60s_timer);
+ // 删除定时器并置为 nullptr
+ osStatus_t ret = osTimerDelete(g_screen60s_timer);
+ if (ret != osOK)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
+ }
+ g_screen60s_timer = nullptr;
+ SCREEN_60S_TIME = 60;
+ }
+ }
+ void AiVoiceModel::reset_ai_screen60s_timer_time()
+ {
+ SCREEN_60S_TIME = 60;
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "reset_ai_screen60s_timer_time %d", SCREEN_60S_TIME);
+ if (nullptr == g_screen60s_timer)
+ {
+ ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON); // 重新常亮屏
+ ai_start_screen60s_timer(); // 开启定时器
+ }
+ }
+
+ bool AiVoiceModel::get_screen60s_timer_is_stop(void)
+ {
+ if(g_screen60s_timer == nullptr)
+ return true;
+ else
+ return false;
+ }
+ static osTimerId_t g_listeningEndHandle = nullptr;
+ static int8_t LISTENING_TIMEOUT = 10; // 10s钟无操作关闭该视图
+ static void AIListeningCallbackProc(int data)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AIListeningCallbackProc %d", LISTENING_TIMEOUT);
+ LISTENING_TIMEOUT--;
+ if (LISTENING_TIMEOUT <= 0)
+ {
+ AiVoiceModel::GetInstance().StopListenAndRecordingUserQuestion(); // 停止聆听用户问题
+ AiVoiceModel::GetInstance().stop_listening_timer(); // 停止聆听定时器
+ if (AiVoiceView::GetInstance() && AivoiceListeningView::GetInstance())
+ {
+ AiVoiceView::GetInstance()->ChangeView(AIVOICE_LISTENING_VIEWID, AIVOICE_THINKING_VIEWID); // 切换到思考中界面
+ AiVoiceModel::GetInstance().AIVoice_StartTimer();
+ }
+ }
+ else
+ {
+ if (AivoiceListeningView::GetInstance())
+ {
+ AivoiceListeningView::GetInstance()->GetShowtimeoutLabel()->SetText(std::to_string(LISTENING_TIMEOUT).c_str());
+ AivoiceListeningView::GetInstance()->GetShowtimeoutLabel()->Invalidate();
+ }
+ }
+ return;
+ }
+ static void AIListeningCallback(int data)
+ {
+ GraphicService::GetInstance()->PostGraphicEvent(std::bind(AIListeningCallbackProc, data));
+ }
+ // 开启一个AI录音的定时器
+ void AiVoiceModel::start_listening_timer(uint32_t interval)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::start_listening_timer");
+ /* -------------------------- 1.检查定时器是否已经存在,如果存在则返回 ------------------------- */
+ if (g_listeningEndHandle != nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer already exists!!");
+ return;
+ }
+ /* --------------------------------- 2.创建定时器 -------------------------------- */
+ g_listeningEndHandle = osTimerNew((osTimerFunc_t)AIListeningCallback, osTimerPeriodic, nullptr, nullptr);
+ // 检查定时器创建是否成功
+ if (g_listeningEndHandle == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer create failed!!");
+ return;
+ }
+ /* ----------------------------- 3.将毫秒转换为系统时钟节拍数 ---------------------------- */
+ int tick = osMs2Tick(interval);
+ /* --------------------------------- 4.启动定时器 -------------------------------- */
+ osStatus_t ret = osTimerStart(g_listeningEndHandle, tick);
+ /* -------------------- 5.检查定时器启动是否成功,如果启动失败,删除定时器并置为 nullptr -------------------- */
+ if (ret != osOK)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
+ if (g_listeningEndHandle != nullptr)
+ {
+ ret = osTimerDelete(g_listeningEndHandle);
+ }
+ g_listeningEndHandle = nullptr;
+ return;
+ }
+ }
+
+ // 停止一个AI录音的定时器
+ void AiVoiceModel::stop_listening_timer(void)
+ {
+ // 检查定时器是否存在
+ if (g_listeningEndHandle != nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::stop_listening_timer");
+ osTimerStop(g_listeningEndHandle);
+ // 删除定时器并置为 nullptr
+ osStatus_t ret = osTimerDelete(g_listeningEndHandle);
+ if (ret != osOK)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
+ }
+ g_listeningEndHandle = nullptr;
+ LISTENING_TIMEOUT = 10;
+ }
+ }
+
+ static osTimerId_t g_ai_is_ready_Handle = nullptr; // 处理查询AI是否就绪定时器
+ static int8_t AI_IS_READY_TIMEOUT = 5; // 5s钟超时
+ static void AI_IS_READY_CallbackProc(int data)
+ {
+ if (AI_IS_READY_TIMEOUT <= 0) // 模型连接失败有5秒超时
+ {
+ AiVoiceModel::GetInstance().stop_ai_isready_timer();
+ AiVoiceView *view_ = AiVoiceView::GetInstance();
+ AiVoicePresenter *p_AiVoicePresenter = AiVoicePresenter::GetInstance();
+ if (view_ != nullptr && p_AiVoicePresenter != nullptr)
+ {
+ if ((view_->GetAiVoiceScrollView(AIVOICE_AIMODE_CONNECTING) != nullptr) &&
+ (view_->GetAiVoiceScrollView(AIVOICE_AIMODE_CONNECTING)->IsVisible()))
+ {
+ p_AiVoicePresenter->ChangeViewAndLogicOperator(AIVOICE_AIMODE_CONNECTING, AIVOICE_AIMODEL_CONNECT_FAILED_VIEWID);
+ }
+ }
+ }
+ return;
+ }
+ static void AI_IS_READY_Callback(int data)
+ {
+ AI_IS_READY_TIMEOUT--;
+ GraphicService::GetInstance()->PostGraphicEvent(std::bind(AI_IS_READY_CallbackProc, data));
+ }
+
+ // 开启一个查询AI是否准备就绪的定时器
+ void AiVoiceModel::start_ai_isready_timer(uint32_t interval)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::start_ai_isready_timer");
+ /* -------------------------- 1.检查定时器是否已经存在,如果存在则返回 ------------------------- */
+ if (g_ai_is_ready_Handle != nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer already exists!!");
+ return;
+ }
+ /* --------------------------------- 2.创建定时器 -------------------------------- */
+ g_ai_is_ready_Handle = osTimerNew((osTimerFunc_t)AI_IS_READY_Callback, osTimerPeriodic, nullptr, nullptr);
+ // 检查定时器创建是否成功
+ if (g_ai_is_ready_Handle == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer create failed!!");
+ return;
+ }
+ /* ----------------------------- 3.将毫秒转换为系统时钟节拍数 ---------------------------- */
+ int tick = osMs2Tick(interval);
+ /* --------------------------------- 4.启动定时器 -------------------------------- */
+ osStatus_t ret = osTimerStart(g_ai_is_ready_Handle, tick);
+ /* -------------------- 5.检查定时器启动是否成功,如果启动失败,删除定时器并置为 nullptr -------------------- */
+ if (ret != osOK)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
+ if (g_ai_is_ready_Handle != nullptr)
+ {
+ ret = osTimerDelete(g_ai_is_ready_Handle);
+ }
+ g_ai_is_ready_Handle = nullptr;
+ return;
+ }
+ return;
+ }
+
+ // 停止一个查询AI是否准备就绪的定时器
+ void AiVoiceModel::stop_ai_isready_timer(void)
+ {
+ // 检查定时器是否存在
+ if (g_ai_is_ready_Handle != nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::stop_ai_isready_timer");
+ osTimerStop(g_ai_is_ready_Handle);
+ // 删除定时器并置为 nullptr
+ osStatus_t ret = osTimerDelete(g_ai_is_ready_Handle);
+ if (ret != osOK)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
+ }
+ g_ai_is_ready_Handle = nullptr;
+ AI_IS_READY_TIMEOUT = 5;
+ }
+ }
+
+ // 设置选择的ai模型
+ void AiVoiceModel::SetSelectAiModel(int index)
+ {
+ ConfigModel::GetInstance()->SetSelectAiModel(index);
+ }
+
+ int AiVoiceModel::GetSelectAiModel(void)
+ {
+ return ConfigModel::GetInstance()->GetSelectAiModel();
+ }
+
+ /*获取已选择的ai模型的textid*/
+ int AiVoiceModel::GetAiModelTextId()
+ {
+ #if 0
+ int language = ConfigModel::GetInstance()->GetLanguage();
+ int textId;
+
+ if (language == 0)
+ {
+ selectAiModelToTextId = {
+ {0, {STR_AIMODES_WENXINYIYAN, 0}},
+ {1, {STR_AIMODES_KIMI, 2}},
+ {2, {STR_AIMODELS_DOUBAO, 3}},
+ // {3, {STR_TONGYI_QIANWEN, 4}},
+ {3, {STR_DEEPSEEK, 4}},
+ {4, {STR_IFLYTEK_SPARK, 5}},
+ {5, {STR_AIMODES_CHATGPT, 1}},
+ };
+ textId = STR_AIMODES_WENXINYIYAN;
+ }
+ else
+ {
+ selectAiModelToTextId = {
+ {0, {STR_AIMODES_CHATGPT, 1}},
+ {1, {STR_AIMODES_WENXINYIYAN, 0}},
+ {2, {STR_AIMODES_KIMI, 2}},
+ {3, {STR_AIMODELS_DOUBAO, 3}},
+ // {4, {STR_TONGYI_QIANWEN, 4}},
+ {4, {STR_DEEPSEEK, 4}},
+ {5, {STR_IFLYTEK_SPARK, 5}},
+ };
+ textId = STR_AIMODES_CHATGPT;
+ }
+ #endif
+ //客户新需求需要改模型顺序:
+ int textId = 0;
+ selectAiModelToTextId = {
+ {0, {STR_DEEPSEEK, 4}},
+ {1, {STR_AIMODES_CHATGPT, 1}},
+ {2, {STR_AIMODELS_DOUBAO, 3}},
+ {3, {STR_AIMODES_WENXINYIYAN, 0}},
+ {4, {STR_AIMODES_KIMI, 2}},
+ {5, {STR_IFLYTEK_SPARK, 5}},
+ };
+ textId = STR_DEEPSEEK;
+
+ // 根据视图ID设置文本ID
+ auto it = selectAiModelToTextId.find(GetSelectAiModel());
+ if (it != selectAiModelToTextId.end())
+ {
+ return it->second.first;
+ }
+
+ return textId;
+ }
+
+}
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-20 15:11:17
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2025-03-19 10:24:14
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoicePresenter.cpp
+ */
+#include "AppViewIDs.h"
+#include "NativeAbility.h"
+#include "aivoice/include/AiVoicePresenter.h"
+#include "aivoice/include/AiVoiceView.h"
+#include "aivoice/include/AiVoiceModel.h"
+#include "common/key_code.h"
+#include <custom_utils.h>
+#include "UiConfig.h"
+#include "iostream"
+#include <string> // For std::string
+#include <unordered_map> // For std::unordered_map
+#include <string> // For std::string
+#include <unordered_map> // For std::unordered_map
+
+#ifdef SUPPORT_BLE_SERVICE
+#include <bleEvent.h>
+#include "bleService.h"
+#endif
+
+#include <unistd.h>
+#include "gfx_utils/mem_check.h"
+
+#include "player/include/PlayersModel.h"
+
+#include "NativeRegisterManager.h"
+namespace OHOS
+{
+
+ REGIST_MENU_PRO(VIEW_AI_VOICE, AiVoiceView, AiVoicePresenter,
+ PNG_APPLIST_AIVOICE_IMAGE_BIG, PNG_APPLIST_AIVOICE_IMAGE,PNG_APPLIST_AIVOICE_IMAGE, "AI全家桶", STR_AI_FAMILY_MEALS);
+
+#define BLE_CONNECT_INTERVAL_HIGH_AI 10
+ // 当前Presenter属性实例化的内存指针
+ static AiVoicePresenter *g_pAiVoicePresenter = nullptr;
+
+ AiVoicePresenter::AiVoicePresenter()
+ {
+#ifdef MEM_CHECK
+ MemCheck::GetInstance()->EnableLeakCheck(true);
+#endif
+ model = &AiVoiceModel::GetInstance();
+ g_pAiVoicePresenter = this;
+ }
+
+ AiVoicePresenter::~AiVoicePresenter()
+ {
+#ifdef MEM_CHECK
+ MemCheck::GetInstance()->EnableLeakCheck(false);
+#endif
+ g_pAiVoicePresenter = nullptr;
+ }
+
+ AiVoicePresenter *AiVoicePresenter::GetInstance()
+ {
+ return g_pAiVoicePresenter;
+ }
+
+ // 启动时执行的逻辑
+ void AiVoicePresenter::OnStart()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnStart");
+ Presenter<AiVoiceView>::OnStart();
+ ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON);
+ // 开启一个60s取消长亮屏timer
+ model->ai_start_screen60s_timer();
+#ifdef SUPPORT_BLE_SERVICE
+ uapi_ble_connect_param_update(BLE_CONNECT_INTERVAL_HIGH_AI);
+#endif
+ }
+
+ // 页面已经展示后的调用逻辑
+ void AiVoicePresenter::OnResume(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnResume");
+ Presenter<AiVoiceView>::OnResume();
+ if (view_ == nullptr)
+ {
+ return;
+ }
+ }
+
+ // 页面准备切换到后台前执行的逻辑
+ 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");
+ Presenter<AiVoiceView>::OnStop();
+ ScreenAlwaysOnCtr(CANCEL_SCREEN_ALWAYS_ON);
+ model->StatusResume();
+ model->AIVoice_StopTimer();
+ model->ai_stop_screen60s_timer();
+ model->stop_listening_timer();
+ model->stop_ai_isready_timer();
+ #ifdef SUPPORT_BLE_SERVICE
+ uapi_ble_connect_param_update(BLE_CONNECT_INTERVAL_SLOW);
+ #endif
+ }
+
+ /*调转到返回结果界面*/
+ bool AiVoicePresenter::JumpToReturnResultTextView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::JumpToReturnResultTextView");
+ if (view_->GetAiVoiceScrollView(AIVOICE_THINKING_VIEWID) != nullptr &&
+ view_->GetAiVoiceScrollView(AIVOICE_THINKING_VIEWID)->IsVisible())
+ {
+ preHeight = 0;
+ ChangeViewAndLogicOperator(AIVOICE_THINKING_VIEWID, AIVOICE_RETURN_RESULT_TEXT_VIEWID);
+ }
+ else
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::JumpToReturnResultTextView fail");
+ return false;
+ }
+ return true;
+ }
+
+ /*跳转到AI聆听界面界面*/
+ bool AiVoicePresenter::ChangeToAIVoiceListeningView(bool val)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::ChangeToAIVoiceListeningView");
+ if (view_->GetAiVoiceScrollView(AIVOICE_AIMODE_CONNECTING) != nullptr && view_->GetAiVoiceScrollView(AIVOICE_AIMODE_CONNECTING)->IsVisible())
+ {
+ model->stop_ai_isready_timer(); // 停止定时器
+ if (val) /*如果查询的AI模型可用跳转到聆听中界面*/
+ {
+ ChangeViewAndLogicOperator(AIVOICE_AIMODE_CONNECTING, AIVOICE_LISTENING_VIEWID);
+ }
+ else
+ {
+ if(model->GetAiModelTextId() == STR_AIMODES_CHATGPT) //如果当前是在chatgpt模型*/
+ {
+ ChangeViewAndLogicOperator(AIVOICE_AIMODE_CONNECTING, AIVOICE_NOTSETAPIKEYS); /*开始对话界面->API Keys notset界面*/
+ }
+ else
+ {
+ ChangeViewAndLogicOperator(AIVOICE_AIMODE_CONNECTING, AIVOICE_AIMODEL_CONNECT_FAILED_VIEWID);
+ }
+ }
+ }
+ else
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::ChangeToAIVoiceListeningView fail");
+ return false;
+ }
+ return true;
+ }
+
+ bool AiVoicePresenter::ChangeToAIVoiceConnectTimeoutView()
+ {
+ if ((view_->GetAiVoiceScrollView(AIVOICE_THINKING_VIEWID) != nullptr) &&
+ (view_->GetAiVoiceScrollView(AIVOICE_THINKING_VIEWID)->IsVisible()))
+ {
+ ChangeViewAndLogicOperator(AIVOICE_THINKING_VIEWID, AIVOICE_CONNECT_TIMEOUT_VIEWID);
+ AivoiceConnectTimeoutView *p_AivoiceConnectTimeoutView = AivoiceConnectTimeoutView::GetInstance();
+ if (p_AivoiceConnectTimeoutView)
+ {
+ p_AivoiceConnectTimeoutView->UpdateNoteText();
+ }
+ }
+ return true;
+ }
+
+ void AiVoicePresenter::FunctionKeyOnClickToChangeAIModel(void)
+ {
+ if(view_->GetAiVoiceScrollView(AIVOICE_STARTCHAT_VIEWID) && view_->GetAiVoiceScrollView(AIVOICE_STARTCHAT_VIEWID)->IsVisible() == true)
+ {
+ int index = model->GetSelectAiModel() + 1;
+ if (index >= AIMODES_MAX_NUM)
+ {
+ index = 0;
+ }
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiModelsPresenter::index = %d", index);
+ model->SetSelectAiModel(index);
+ view_->ChangeAiModelAndUpdateComponentsStatus();
+ model->reset_ai_screen60s_timer_time(); // 重置60s取消常亮屏timer
+ }
+ return;
+ }
+
+ // 右滑切换模型
+ void AiVoicePresenter::DragLeftToRightChangeAIModel(void)
+ {
+ if(view_->GetAiVoiceScrollView(AIVOICE_STARTCHAT_VIEWID) && view_->GetAiVoiceScrollView(AIVOICE_STARTCHAT_VIEWID)->IsVisible() == true)
+ {
+ int index = model->GetSelectAiModel() + 1;
+ if (index >= AIMODES_MAX_NUM)
+ {
+ index = 0;
+ }
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiModelsPresenter::index = %d", index);
+ model->SetSelectAiModel(index);
+ view_->ChangeAiModelAndUpdateComponentsStatus();
+ }
+ return;
+ }
+
+ // 左滑切换模型
+ void AiVoicePresenter::DragRightToLetfChangeAIModel(void)
+ {
+ if(view_->GetAiVoiceScrollView(AIVOICE_STARTCHAT_VIEWID) && view_->GetAiVoiceScrollView(AIVOICE_STARTCHAT_VIEWID)->IsVisible() == true)
+ {
+ int index = model->GetSelectAiModel() - 1;
+ if (index < 0)
+ {
+ index = AIMODES_CHATGPT;
+ }
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiModelsPresenter::index = %d", index);
+ model->SetSelectAiModel(index);
+ view_->ChangeAiModelAndUpdateComponentsStatus();
+ }
+ return;
+ }
+
+ bool AiVoicePresenter::ChangeViewAndLogicOperator(int16_t hideView, int16_t showView)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::ChangeViewOperator");
+
+ if (hideView > MAX_AIVOICE_VIEWID)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Overstep ones bounds");
+ return false;
+ }
+
+ /* ------------------------ 进行界面切换的时候重置60s取消常亮屏timer ------------------------ */
+ model->reset_ai_screen60s_timer_time();
+ /* -------------------------------------------------------------------------- */
+ view_->ChangeView(hideView, showView); // 默认先进行视图切换
+
+ switch (hideView)
+ {
+ case AIVOICE_STARTCHAT_VIEWID:
+ model->QuerySelectedAiModelIsConnect(); /*查询用户选择的AI模型是否已经连接*/
+ if (showView == AIVOICE_LISTENING_VIEWID)
+ {
+ model->StartListenAndRecordingUserQuestion();
+ }
+ else if (showView == AIVOICE_AIMODE_CONNECTING)
+ {
+ model->start_ai_isready_timer(); /*开启一个查询AI模型是否连接成功定时器*/
+ }
+ break;
+
+ case AIVOICE_AIMODE_CONNECTING:
+ if (showView == AIVOICE_LISTENING_VIEWID)
+ {
+ model->StartListenAndRecordingUserQuestion();
+ }
+ break;
+
+ case AIVOICE_LISTENING_VIEWID:
+ model->StopListenAndRecordingUserQuestion();
+ model->stop_listening_timer();
+ if (showView == AIVOICE_THINKING_VIEWID) // 聆听中->思考中界面
+ {
+ model->AIVoice_StartTimer();
+ }
+ break;
+
+ case AIVOICE_THINKING_VIEWID:
+ model->AIVoice_StopTimer();
+ break;
+
+ case AIVOICE_RETURN_RESULT_TEXT_VIEWID:
+ AiVoiceModel::GetInstance().ClearQuestionAndAiAnswerStr(); // 清空上次用户问题和Ai回答字符串
+ AiVoiceModel::GetInstance().SetIsClickable(false);
+ AiVoiceModel::GetInstance().SetIsLimitDisplayed(false);
+ if (showView == AIVOICE_LISTENING_VIEWID)
+ {
+ model->StartListenAndRecordingUserQuestion();
+ }
+ break;
+
+ default:
+ // Handle other cases if needed
+ break;
+ }
+
+ return true;
+ }
+
+ // 处理手点击屏幕切换AI模型
+ bool AiVoicePresenter::OnClick(UIView &view, const ClickEvent &event)
+ {
+ UNUSED(event);
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnClick");
+
+ model->reset_ai_screen60s_timer_time(); // 重置60s取消常亮屏timer
+
+ if (strcmp(view.GetViewId(), AIVOICE_IMGAE_VIEW_ID) == 0) /*点击的是Ai模型就切换模型*/
+ {
+ int index = model->GetSelectAiModel() + 1;
+ if (index >= AIMODES_MAX_NUM)
+ {
+ index = 0;
+ }
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiModelsPresenter::index = %d", index);
+ model->SetSelectAiModel(index);
+ view_->ChangeAiModelAndUpdateComponentsStatus();
+ }
+
+ return true;
+ }
+
+ bool AiVoicePresenter::OnPress(UIView& view, const PressEvent& event)
+ {
+ UNUSED(event);
+ std::string viewId = view.GetViewId();
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnRelease %s", viewId.c_str());
+ /* ----------------------------- 重置60s取消常亮屏timer ---------------------------- */
+ model->reset_ai_screen60s_timer_time();
+ /* -------------------------------------------------------------------------- */
+ std::unordered_map<std::string, std::pair<int16_t, int16_t>> viewIdMap = {
+ {AIVOICERETURNRESULTTEXT_RETURN_BUTTON_VIEW_ID, {AIVOICE_RETURN_RESULT_TEXT_VIEWID, AIVOICE_STARTCHAT_VIEWID}}, // 返回一级界面,并清除手表聊天记录
+ {AIVOICERETURNRESULTTEXT_CONTINUECHAT_BUTTON_VIEW_ID, {AIVOICE_RETURN_RESULT_TEXT_VIEWID, AIVOICE_LISTENING_VIEWID}}, // 返回继续聆听,并清除手表聊天记录
+ };
+ auto it = viewIdMap.find(viewId);
+ if (it != viewIdMap.end())
+ {
+ #if 0
+ if(!model->GetIsClickable())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "当前还不可点击");
+ return true;
+ }
+ #endif
+ if (it->first == AIVOICERETURNRESULTTEXT_CONTINUECHAT_BUTTON_VIEW_ID) // 点击继续对话按钮要发取消当前对话指令,避免AI回应中途按继续对话按钮没有取消上一次对话问题
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CancelCurAIChat");
+ AiVoiceModel::GetInstance().CancelCurAIChat();
+ // AiVoiceModel::GetInstance().sendAIIsReady();
+ PlayersModel::GetInstance()->HandPausePhoneMusic(); // 暂停手机音乐
+ PlayersModel::GetInstance()->PlayerPause(); // 暂停手机音乐
+ }
+ ChangeViewAndLogicOperator(it->second.first, it->second.second);
+ return true;
+ }
+ return true;
+ }
+
+ bool AiVoicePresenter::OnRelease(UIView &view, const ReleaseEvent &event)
+ {
+ UNUSED(event);
+ std::string viewId = view.GetViewId();
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnRelease %s", viewId.c_str());
+ /* ----------------------------- 重置60s取消常亮屏timer ---------------------------- */
+ model->reset_ai_screen60s_timer_time();
+ /* -------------------------------------------------------------------------- */
+
+ // if ((viewId == AIVOICE_CHAT_BUTTON_VIEW_ID) && model->IsExistOpenAIAPIKeys() == false) // 如果点击的是(对话按钮)且未配置apikey
+ // {
+ // ChangeViewAndLogicOperator(AIVOICE_STARTCHAT_VIEWID, AIVOICE_NOTSETAPIKEYS); /*开始对话界面->API Keys notset界面*/
+ // return true;
+ // }
+ if (viewId == AIVOICE_APIKEYS_BUTTON_VIEW_ID) // 如果点击的是API Keys按钮(注:暂时不用)
+ {
+ if (model->IsExistOpenAIAPIKeys() == true)
+ {
+ ChangeViewAndLogicOperator(AIVOICE_STARTCHAT_VIEWID, AIVOICE_SETAPIKEYS); /*开始对话界面->API Keys set界面*/
+ }
+ else
+ {
+ ChangeViewAndLogicOperator(AIVOICE_STARTCHAT_VIEWID, AIVOICE_NOTSETAPIKEYS); /*开始对话界面->API Keys notset界面*/
+ }
+ return true;
+ }
+ else if (viewId == AIVOICE_START_CHAT_BUTTON_VIEW_ID) // 如果点击的是开始对话按钮
+ {
+ PlayersModel::GetInstance()->HandPausePhoneMusic(); // 暂停手机音乐
+ PlayersModel::GetInstance()->PlayerPause(); // 暂停手机音乐
+ /*
+ * 进入对话流程:
+ * 1.当手表4G网络正常+与app连接正常 -> 通过4G调用大模型
+ * 2.只有手表4G网络正常 -> 通过4G调用大模型
+ * 3.只有与APP蓝牙连接正常 -> 通过蓝牙连接APP调用大模型
+ * 4.两者连接都异常 -> 返回错误
+ */
+ bool netWork4GState = model->GetMobileDataIsOpen();
+ bool appBluetoothConnectState = model->GetAPPBluetoothIsConnect();
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "netWork4GState = %d,appBluetoothConnectState = %d", netWork4GState, appBluetoothConnectState);
+
+ if (netWork4GState) // 1.手表4G网络正常
+ {
+ // 通过4G调用大模型
+ }
+ else if (appBluetoothConnectState) // 3.只有与APP蓝牙连接正常
+ {
+ // 通过蓝牙连接APP调用大模型
+ ChangeViewAndLogicOperator(AIVOICE_STARTCHAT_VIEWID, AIVOICE_AIMODE_CONNECTING); // LOADING
+ }
+ else // 4.两者连接都异常
+ {
+ // 返回错误
+ ChangeViewAndLogicOperator(AIVOICE_STARTCHAT_VIEWID, AIVOICE_ALERT_APPBLUETOOTH_AND_4GNETWORK_VIEWID);
+ // ChangeViewAndLogicOperator(AIVOICE_STARTCHAT_VIEWID, AIVOICE_AIMODEL_CONNECT_FAILED_VIEWID);
+ }
+ return true;
+ }
+ else if (viewId == FINISH_SPEAKING_BUTTON_VIEW_ID) // 如果点击的是说话完毕按钮
+ {
+ ChangeViewAndLogicOperator(AIVOICE_LISTENING_VIEWID, AIVOICE_THINKING_VIEWID);
+ return true;
+ }
+
+ std::unordered_map<std::string, std::pair<int16_t, int16_t>> viewIdMap = {
+ {ALERT_APPBLUETOOTH_AND_4GNETWORK_ENSURE_BUTTON_VIEW_ID, {AIVOICE_ALERT_APPBLUETOOTH_AND_4GNETWORK_VIEWID, AIVOICE_STARTCHAT_VIEWID}}, // 返回一级界面
+ {AIMODEL_CONNECT_FAILED_ENSURE_BUTTON_VIEW_ID, {AIVOICE_AIMODEL_CONNECT_FAILED_VIEWID, AIVOICE_STARTCHAT_VIEWID}}, // 返回一级界面
+ {AIVOICECONNECTTIMEOUT_ENSURE_BUTTON_VIEW_ID, {AIVOICE_CONNECT_TIMEOUT_VIEWID, AIVOICE_STARTCHAT_VIEWID}}, // 返回一级界面
+ {CANCEL_THINKING_BUTTON_VIEW_ID, {AIVOICE_THINKING_VIEWID, AIVOICE_STARTCHAT_VIEWID}}, // 返回一级界面
+ {AIVOICECONNECTINGVIEW_CANCEL_BUTTON_VIEW_ID, {AIVOICE_AIMODE_CONNECTING, AIVOICE_STARTCHAT_VIEWID}}, // 返回一级界面
+ // {AIVOICERETURNRESULTTEXT_RETURN_BUTTON_VIEW_ID, {AIVOICE_RETURN_RESULT_TEXT_VIEWID, AIVOICE_STARTCHAT_VIEWID}}, // 返回一级界面,并清除手表聊天记录
+ // {AIVOICERETURNRESULTTEXT_CONTINUECHAT_BUTTON_VIEW_ID, {AIVOICE_RETURN_RESULT_TEXT_VIEWID, AIVOICE_LISTENING_VIEWID}}, // 返回继续聆听,并清除手表聊天记录
+ };
+ auto it = viewIdMap.find(viewId);
+ if (it != viewIdMap.end())
+ {
+ // if (it->first == AIVOICERETURNRESULTTEXT_CONTINUECHAT_BUTTON_VIEW_ID) // 点击继续对话按钮要发取消当前对话指令,避免AI回应中途按继续对话按钮没有取消上一次对话问题
+ // {
+ // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CancelCurAIChat");
+ // AiVoiceModel::GetInstance().CancelCurAIChat();
+ // PlayersModel::GetInstance()->HandPausePhoneMusic(); // 暂停手机音乐
+ // PlayersModel::GetInstance()->PlayerPause(); // 暂停手机音乐
+ // }
+ ChangeViewAndLogicOperator(it->second.first, it->second.second);
+ return true;
+ }
+ return true;
+ }
+
+ bool AiVoicePresenter::OnDrag(UIView &view, const DragEvent &event)
+ {
+ UNUSED(view);
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnDrag");
+ if ((event.GetDeltaX() > X_DRAG_OFFSET) && (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) // 拖动过程中判断是否是水平滑动
+ {
+ AiVoicePresenter::X_DRAG_FLAG = true;
+ }
+ return true;
+ }
+
+ bool AiVoicePresenter::OnDragEnd(UIView &view, const DragEvent &event)
+ {
+ UNUSED(view);
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnDragEnd");
+ UIScrollView *scrollView = dynamic_cast<UIScrollView *>(&view);
+ if (scrollView == nullptr)
+ {
+ return false;
+ }
+
+ model->reset_ai_screen60s_timer_time(); // 重置60s取消常亮屏timer
+
+ if (event.GetDragDirection() == DragEvent::DIRECTION_RIGHT_TO_LEFT) /*左滑*/
+ {
+ DragRightToLetfChangeAIModel();
+ }
+ else if (event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT && AiVoicePresenter::X_DRAG_FLAG) /*右滑*/
+ {
+ if (scrollView == view_->GetAiVoiceScrollView(AIVOICE_STARTCHAT_VIEWID))
+ {
+ /*AI对话界面右滑退出当前Slice*/
+ // NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+ DragLeftToRightChangeAIModel();
+ }
+ else if (scrollView == view_->GetAiVoiceScrollView(AIVOICE_ALERT_APPBLUETOOTH_AND_4GNETWORK_VIEWID))
+ {
+ /*APP蓝牙与4G网络都连接异常界面右滑退回到开始对话界面*/
+ ChangeViewAndLogicOperator(AIVOICE_ALERT_APPBLUETOOTH_AND_4GNETWORK_VIEWID, AIVOICE_STARTCHAT_VIEWID);
+ }
+ else if (scrollView == view_->GetAiVoiceScrollView(AIVOICE_AIMODEL_CONNECT_FAILED_VIEWID))
+ {
+ /*模型连接失败弹窗界面右滑退回到开始对话界面*/
+ ChangeViewAndLogicOperator(AIVOICE_AIMODEL_CONNECT_FAILED_VIEWID, AIVOICE_STARTCHAT_VIEWID);
+ }
+ else if (scrollView == view_->GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID))
+ {
+ /*聆听中界面右滑退回到AI对话界面*/
+ ChangeViewAndLogicOperator(AIVOICE_LISTENING_VIEWID, AIVOICE_STARTCHAT_VIEWID);
+ }
+ else if (scrollView == view_->GetAiVoiceScrollView(AIVOICE_THINKING_VIEWID))
+ {
+ /*思考中界面右滑退到AI对话界面*/
+ ChangeViewAndLogicOperator(AIVOICE_THINKING_VIEWID, AIVOICE_STARTCHAT_VIEWID);
+ }
+ else if (scrollView == view_->GetAiVoiceScrollView(AIVOICE_CONNECT_TIMEOUT_VIEWID))
+ {
+ /*连接超时界面右滑退到AI对话界面*/
+ ChangeViewAndLogicOperator(AIVOICE_CONNECT_TIMEOUT_VIEWID, AIVOICE_STARTCHAT_VIEWID);
+ }
+ else if (scrollView == view_->GetAiVoiceScrollView(AIVOICE_AIMODE_CONNECTING))
+ {
+ /*连接超时界面右滑退到AI对话界面*/
+ ChangeViewAndLogicOperator(AIVOICE_AIMODE_CONNECTING, AIVOICE_STARTCHAT_VIEWID);
+ }
+ AiVoicePresenter::X_DRAG_FLAG = false;
+ }
+ else if (model->GetAiModelTextId() == STR_AIMODES_CHATGPT && event.GetDragDirection() == DragEvent::DIRECTION_BOTTOM_TO_TOP) /*上滑*/
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "DIRECTION_BOTTOM_TO_TOP");
+ if (model->IsExistOpenAIAPIKeys() == true)
+ {
+ ChangeViewAndLogicOperator(AIVOICE_STARTCHAT_VIEWID, AIVOICE_SETAPIKEYS); /*开始对话界面->API Keys set界面*/
+ }
+ else
+ {
+ ChangeViewAndLogicOperator(AIVOICE_STARTCHAT_VIEWID, AIVOICE_NOTSETAPIKEYS); /*开始对话界面->API Keys notset界面*/
+ }
+ }
+ return true;
+ }
+
+ bool AiVoicePresenter::OnKeyAct(UIView &view, const KeyEvent &event) // 增加按键事件
+ {
+ UNUSED(view);
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnKeyAct");
+ uint16_t keyID = event.GetKeyId();
+ uint16_t keyState = event.GetState();
+ // 如果是power键,且是亮屏状态,按键释放就返回上一级
+ if (keyID == static_cast<uint16_t>(ZliteKeyCode::ZLITE_KEY_POWER) && keyState == 1 && uapi_get_screen_state() == 0)
+ {
+ NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+ AiVoiceModel::GetInstance().CancelCurAIChat();
+ }
+ return true;
+ }
+
+ void AiVoicePresenter::OnPickerStoped(UIPicker &picker)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnPickerStoped,%d", picker.GetSelected());
+ if(view_->GetAiVoiceScrollView(AIVOICE_STARTCHAT_VIEWID) && view_->GetAiVoiceScrollView(AIVOICE_STARTCHAT_VIEWID)->IsVisible() == true)
+ {
+ model->SetSelectAiModel(picker.GetSelected());
+ view_->ChangeAiModelAndUpdateComponentsStatus();
+ }
+ return;
+ }
+
+ // 计算聊天内容ItemView的高度
+ void AiVoicePresenter::calculateChatContentItemViewHeight(std::string text, bool flag)
+ {
+ const char *Text = text.c_str();
+ UILabel label;
+ label.SetPosition(53, 100);
+ label.Resize(flag ? 280 : 200, 60);
+ label.SetStyle(STYLE_TEXT_FONT, 26);
+ label.SetStyle(STYLE_LINE_HEIGHT, 30);
+ label.SetText(Text);
+ label.SetLineBreakMode(UILabel::LINE_BREAK_WRAP);
+ label.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ label.SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, 26);
+
+ if (label.GetTextHeight() > preHeight)
+ {
+ preHeight = label.GetTextHeight();
+ isScroll = true;
+ }
+ return;
+ }
+
+ //监听高度是否变化
+ void AiVoicePresenter::Notify()
+ {
+ if ((view_->GetAiVoiceScrollView(AIVOICE_RETURN_RESULT_TEXT_VIEWID) != nullptr) &&
+ (view_->GetAiVoiceScrollView(AIVOICE_RETURN_RESULT_TEXT_VIEWID)->IsVisible()))
+ {
+ if (isScroll)
+ {
+ // 监听,让List实现滚动
+ AivoiceReturnResultTextView::GetInstance()->GetChatContentList()->ScrollBy(-120);
+ isScroll = false;
+ }
+ }
+ return;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-05-07 11:25:58
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2025-03-06 16:07:08
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/AiVoice/src/AiVoiceView.cpp
+ */
+#include "aivoice/include/AiVoicePresenter.h"
+#include "aivoice/include/AiVoiceView.h"
+#include "aivoice/include/AiVoiceModel.h"
+#include "wearable_log.h"
+#include "ui_resource_string.h"
+#include "ConfigModel.h"
+namespace OHOS
+{
+
+ static AiVoiceView *g_pAiVoiceView{nullptr};
+
+ AiVoiceView::AiVoiceView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::AiVoiceView");
+ g_pAiVoiceView = this;
+ }
+
+ AiVoiceView::~AiVoiceView()
+ {
+ ClearAll();
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::~AiVoiceView");
+ g_pAiVoiceView = nullptr;
+ }
+
+ AiVoiceView *AiVoiceView::GetInstance()
+ {
+ return g_pAiVoiceView;
+ }
+
+ void AiVoiceView::ClearAll(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ClearAll");
+ if (viewInitStatus)
+ {
+
+
+ if (AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID] != nullptr)
+ {
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]->RemoveAll();
+
+ delete title;
+ title = nullptr;
+
+ delete aiModelImage;
+ aiModelImage = nullptr;
+
+ delete startChatButton;
+ startChatButton = nullptr;
+
+ delete startChatLabel;
+ startChatLabel = nullptr;
+
+ delete chatButton;
+ chatButton = nullptr;
+
+ delete chatLabel;
+ chatLabel = nullptr;
+
+ delete apiKeysLabel;
+ apiKeysLabel = nullptr;
+
+ delete apiKeysButton;
+ apiKeysButton = nullptr;
+
+ delete aiModelPicker;
+ aiModelPicker = nullptr;
+
+ delete buttonBgImage;
+ buttonBgImage = nullptr;
+
+ delete upImage;
+ upImage = nullptr;
+
+ delete AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID];
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID] = nullptr;
+ }
+
+ if (p_AiVoiceBluetoothFailedStartView != nullptr)
+ {
+ delete p_AiVoiceBluetoothFailedStartView;
+ p_AiVoiceBluetoothFailedStartView = nullptr;
+ }
+
+ if (p_AivoiceMobileDataFailedStartView != nullptr)
+ {
+ delete p_AivoiceMobileDataFailedStartView;
+ p_AivoiceMobileDataFailedStartView = nullptr;
+ }
+
+ if (p_AivoiceConnectTimeoutView != nullptr)
+ {
+ delete p_AivoiceConnectTimeoutView;
+ p_AivoiceConnectTimeoutView = nullptr;
+ }
+
+ if (p_AivoiceListeningView != nullptr)
+ {
+ delete p_AivoiceListeningView;
+ p_AivoiceListeningView = nullptr;
+ }
+
+ if (p_AivoiceThinkingView != nullptr)
+ {
+ delete p_AivoiceThinkingView;
+ p_AivoiceThinkingView = nullptr;
+ }
+
+ if (p_AivoiceReturnResultTextView != nullptr)
+ {
+ delete p_AivoiceReturnResultTextView;
+ p_AivoiceReturnResultTextView = nullptr;
+ }
+
+ if (p_SetApiKeysView != nullptr)
+ {
+ delete p_SetApiKeysView;
+ p_SetApiKeysView = nullptr;
+ }
+
+ if (p_NotSetApiKeysView != nullptr)
+ {
+ delete p_NotSetApiKeysView;
+ p_NotSetApiKeysView = nullptr;
+ }
+
+ if (p_ApiKeysDeleteView != nullptr)
+ {
+ delete p_ApiKeysDeleteView;
+ p_ApiKeysDeleteView = nullptr;
+ }
+
+ if (p_AiVoiceConnectingView != nullptr)
+ {
+ delete p_AiVoiceConnectingView;
+ p_AiVoiceConnectingView = nullptr;
+ }
+ }
+ }
+
+ UILabelExt *AiVoiceView::AiVoiceViewLabelInit(LabelConfig &labelconfig)
+ {
+ UILabelExt *label = new UILabelExt();
+ if (label == nullptr)
+ {
+ return nullptr;
+ }
+ label->SetPosition(labelconfig.left, labelconfig.top, labelconfig.width, labelconfig.height);
+ label->SetStyle(STYLE_TEXT_FONT, labelconfig.fontSize);
+ label->SetStyle(STYLE_LINE_HEIGHT, labelconfig.lineHeigh);
+ //TOOD: 待优化
+ if(labelconfig.textId == STR_DEEPSEEK) {
+ label->SetText("DeepSeek");
+ } else
+ label->SetTextId(labelconfig.textId);
+ label->SetLineBreakMode(labelconfig.lineBreakMode);
+ label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ label->SetRollSpeed(23);
+ label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize);
+ 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);
+ Image->SetSrc(imageconfig.src);
+ return Image;
+ }
+
+ UIButton *AiVoiceView::AiVoiceViewButtonInit(ButtonConfig &buttonconfig)
+ {
+ UIButton *button = new UIButton();
+ if (button == nullptr)
+ {
+ return nullptr;
+ }
+ button->SetPosition(buttonconfig.x, buttonconfig.y, buttonconfig.w, buttonconfig.h);
+ button->SetViewId(buttonconfig.ViewId);
+ button->SetStyle(STYLE_BACKGROUND_COLOR, 0xff4fc34c);
+ button->SetStyle(STYLE_BACKGROUND_OPA, 0x00);
+ button->SetStyleForState(STYLE_BACKGROUND_COLOR, 0x00, UIButton::PRESSED);
+ button->SetOnTouchListener(presenter_);
+
+ return button;
+ }
+
+ bool AiVoiceView::CreateAiVoiceViewLabel(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::CreateAiVoiceViewLabel");
+ LabelConfig labelConfig = {
+ .left = 83,
+ .top = 50,
+ .width = 300,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = AiVoiceModel::GetInstance().GetAiModelTextId(),
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ title = AiVoiceViewLabelInit(labelConfig);
+ if (title == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "title new fail!");
+ return false;
+ }
+ /* ----------------------------- startChatLabel ----------------------------- */
+ labelConfig = {
+ .left = 133,
+ .top = 348,
+ .width = 200,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = STR_START_CHAT, /*开始对话*/
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ startChatLabel = AiVoiceViewLabelInit(labelConfig);
+ if (startChatLabel == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "startChatLabel new fail!");
+ return false;
+ }
+ startChatLabel->SetVisible(false);
+ /* -------------------------------- ChatLabel ------------------------------- */
+ labelConfig = {
+ .left = 93,
+ .top = 350,
+ .width = 100,
+ .height = 30,
+ .fontSize = 26,
+ .lineHeigh = 30,
+ .textId = STR_CHAT, /*对话*/
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ chatLabel = AiVoiceViewLabelInit(labelConfig);
+ if (chatLabel == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "chatLabel new fail!");
+ return false;
+ }
+ chatLabel->SetVisible(false);
+ /* ------------------------------ apiKeysLabel ------------------------------ */
+ labelConfig = {
+ .left = 273,
+ .top = 350,
+ .width = 100,
+ .height = 30,
+ .fontSize = 26,
+ .lineHeigh = 30,
+ .textId = STR_API_KEYS, /*API Keys标签*/
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ apiKeysLabel = AiVoiceViewLabelInit(labelConfig);
+ if (apiKeysLabel == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "apiKeysLabel new fail!");
+ return false;
+ }
+ apiKeysLabel->SetVisible(false);
+
+ return true;
+ }
+
+ bool AiVoiceView::CreateAiVoiceViewImageView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::CreateAiVoiceViewImageView");
+ ImageConfig imagecinfig = {
+ .x = 173,
+ .y = 143,
+ .w = 120,
+ .h = 120,
+ .src = "",
+ };
+
+ // 根据视图ID设置文本ID
+ auto it = TextIdToImagePath.find(AiVoiceModel::GetInstance().GetAiModelTextId());
+ if (it != TextIdToImagePath.end())
+ {
+ imagecinfig.src = it->second;
+ }
+
+ aiModelImage = AiVoiceViewImageView(imagecinfig);
+ if (aiModelImage == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::aiModelImage is nullptr!!");
+ return false;
+ }
+ aiModelImage->SetTouchable(true);
+ aiModelImage->SetViewId(AIVOICE_IMGAE_VIEW_ID);
+ aiModelImage->SetOnClickListener(presenter_);
+ /* -------------------------------- buttonBgImage -------------------------------- */
+ imagecinfig = {
+ .x = 208,
+ .y = 340,
+ .w = 48,
+ .h = 56,
+ .src = "/user/res/AIVoice/ai_chart_icon.bin",
+ };
+ buttonBgImage = AiVoiceViewImageView(imagecinfig);
+ if (buttonBgImage == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::aiModelImage is nullptr!!");
+ return false;
+ }
+ /* --------------------------------- upImage -------------------------------- */
+ imagecinfig = {
+ .x = 213,
+ .y = static_cast<int16_t>(buttonBgImage->GetY() + buttonBgImage->GetHeight() + 10),
+ .w = 40,
+ .h = 40,
+ .src = "/user/res/Sleep/up.bin",
+ };
+ upImage = AiVoiceViewImageView(imagecinfig);
+ if (upImage == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::aiModelImage is nullptr!!");
+ return false;
+ }
+ upImage->SetVisible(false);
+ return true;
+ }
+
+ bool AiVoiceView::CreateAiVoiceViewButton(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::CreateAiVoiceViewButton");
+ /* ----------------------------- startChatButton ---------------------------- */
+ ButtonConfig buttonconfig = {
+ .x = 43,
+ .y = 328,
+ .w = 380,
+ .h = 80,
+ .ViewId = AIVOICE_START_CHAT_BUTTON_VIEW_ID,
+ };
+ startChatButton = AiVoiceViewButtonInit(buttonconfig);
+ if (startChatButton == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "startChatButton new fail!");
+ return false;
+ }
+ startChatButton->SetVisible(false);
+ const char *image = "/user/res/AIVoice/ai_chart_icon_bg.bin";
+ startChatButton->SetImageSrc(image, image);
+ /* ------------------------------- chatButton ------------------------------- */
+ buttonconfig = {
+ .x = 43,
+ .y = 328,
+ .w = 380,
+ .h = 80,
+ // .ViewId = AIVOICE_CHAT_BUTTON_VIEW_ID,
+ .ViewId = AIVOICE_START_CHAT_BUTTON_VIEW_ID,
+ };
+ chatButton = AiVoiceViewButtonInit(buttonconfig);
+ if (chatButton == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "chatButton new fail!");
+ return false;
+ }
+ chatButton->SetVisible(false);
+ chatButton->SetImageSrc(image, image);
+ /* ------------------------------ apiKeysButton ----------------------------- */
+ buttonconfig = {
+ .x = 238,
+ .y = 320,
+ .w = 170,
+ .h = 90,
+ .ViewId = AIVOICE_APIKEYS_BUTTON_VIEW_ID,
+ };
+ apiKeysButton = AiVoiceViewButtonInit(buttonconfig);
+ if (apiKeysButton == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "apiKeysButton new fail!");
+ return false;
+ }
+ apiKeysButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919);
+ apiKeysButton->SetVisible(false);
+
+ return true;
+ }
+
+ bool AiVoiceView::CreateAiVoiceViewPicker(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::CreateAiVoiceViewPicker");
+ if (aiModelPicker == nullptr)
+ {
+ aiModelPicker = new UIPicker();
+ if (aiModelPicker == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "aiModelPicker new fail!");
+ return false;
+ }
+ aiModelPicker->SetPosition(203, 203, 60, 60);
+ aiModelPicker->SetViewId(AIVOICE_PICKER_VIEW_ID);
+ aiModelPicker->SetStyle(STYLE_BACKGROUND_COLOR, 0xffffffff);
+ aiModelPicker->SetStyle(STYLE_BACKGROUND_OPA, 0x00);
+ aiModelPicker->SetStyle(STYLE_BORDER_RADIUS, 150);
+ aiModelPicker->SetItemHeight(40);
+ aiModelPicker->SetLoopState(true);
+ aiModelPicker->SetRotateFactor(1.0);
+ aiModelPicker->RequestFocus();
+ aiModelPicker->RegisterSelectedListener(presenter_);
+ aiModelPicker->SetTextColor(Color::GetColorFromRGBA(0x00, 0x00, 0x00, 0xff), Color::GetColorFromRGBA(0xff, 0x00, 0x00, 0xff));
+ const char *uiPicker1Data[] = {"0", "1", "2", "3", "4", "5"};
+ aiModelPicker->SetValues(uiPicker1Data, sizeof(uiPicker1Data) / sizeof(uiPicker1Data[0]));
+ }
+
+ return true;
+ }
+
+ bool AiVoiceView::CreateAiVoiceScrollView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::CreateAiVoiceScrollView");
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID] = new UIScrollView();
+ if (AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID] == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::CreateAiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID] new fail!");
+ return false;
+ }
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]->SetPosition(0, 0, 466, 466);
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]->SetTouchable(true);
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]->SetDraggable(true);
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]->SetOnDragListener(presenter_);
+ AddViewToRootContainer(AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]);
+
+ return true;
+ }
+
+ void AiVoiceView::CreateAiVoiceView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::CreateAiVoiceView");
+ if (!CreateAiVoiceScrollView() || !CreateAiVoiceViewImageView() || !CreateAiVoiceViewPicker() ||
+ !CreateAiVoiceViewLabel() || !CreateAiVoiceViewButton())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::CreateAiVoiceView fail!");
+ return;
+ }
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]->Add(title);
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]->Add(aiModelPicker);
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]->Add(aiModelImage);
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]->Add(startChatButton);
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]->Add(startChatLabel);
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]->Add(chatButton);
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]->Add(chatLabel);
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]->Add(apiKeysButton);
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]->Add(apiKeysLabel);
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]->Add(buttonBgImage);
+ AiVoiceScrollView[AIVOICE_STARTCHAT_VIEWID]->Add(upImage);
+ }
+
+ void AiVoiceView::OnStart()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::OnStart");
+
+
+ if (!viewInitStatus)
+ {
+ CreateAiVoiceView();
+ viewInitStatus = true;
+ }
+
+ SetAiVoiceViewAllComponentsVisibilityStatus();
+
+ RootView::GetInstance()->SetOnKeyActListener(presenter_);
+ return;
+ }
+
+
+
+ /*切换到开始对话Ai界面*/
+ bool AiVoiceView::ChangeAiVoiceStartChatView(int16_t thisView)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoiceStartChatView");
+ if (AiVoiceScrollView[thisView] == nullptr)
+ {
+ AddViewToRootContainer(AiVoiceScrollView[thisView]);
+ }
+ AiVoiceModel::GetInstance().CancelCurAIChat();
+ return true;
+ }
+
+ /*切换到APP蓝牙或4G网络未连接界面界面*/
+ bool AiVoiceView::ChangeAiVoiceBluetoothFailedStartView(int16_t thisView)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoiceBluetoothFailedStartView");
+ if (AiVoiceScrollView[thisView] == nullptr)
+ {
+ p_AiVoiceBluetoothFailedStartView = new AiVoiceBluetoothFailedStartView();
+ if (p_AiVoiceBluetoothFailedStartView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ // AiVoiceScrollView[thisView] = p_AiVoiceBluetoothFailedStartView->CreateAiVoiceBluetoothFailedStartView();
+ UIScrollView *scrollview = p_AiVoiceBluetoothFailedStartView->CreateAiVoiceBluetoothFailedStartView();
+ if (scrollview == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ AiVoiceScrollView[thisView] = scrollview;
+ AddViewToRootContainer(AiVoiceScrollView[thisView]);
+ }
+ return true;
+ }
+
+ /*切换到模型连接失败界面*/
+ bool AiVoiceView::ChangeAiVoiceMobileDataFailedStartView(int16_t thisView)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoiceMobileDataFailedStartView");
+ if (AiVoiceScrollView[thisView] == nullptr)
+ {
+ p_AivoiceMobileDataFailedStartView = new AivoiceMobileDataFailedStartView();
+ if (p_AivoiceMobileDataFailedStartView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ // AiVoiceScrollView[thisView] = p_AivoiceMobileDataFailedStartView->CreateAivoiceMobileDataFailedStartView();
+ UIScrollView *scrollview = p_AivoiceMobileDataFailedStartView->CreateAivoiceMobileDataFailedStartView();
+ if (scrollview == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ AiVoiceScrollView[thisView] = scrollview;
+ AddViewToRootContainer(AiVoiceScrollView[thisView]);
+ }
+ return true;
+ }
+
+ /*切换到连接超时界面*/
+ bool AiVoiceView::ChangeAiVoicConnectTimeoutView(int16_t thisView)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoicConnectTimeoutView");
+ if (AiVoiceScrollView[thisView] == nullptr)
+ {
+ p_AivoiceConnectTimeoutView = new AivoiceConnectTimeoutView();
+ if (p_AivoiceConnectTimeoutView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ // AiVoiceScrollView[thisView] = p_AivoiceConnectTimeoutView->CreateAivoiceConnectTimeoutView();
+ UIScrollView *scrollview = p_AivoiceConnectTimeoutView->CreateAivoiceConnectTimeoutView();
+ if (scrollview == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ AiVoiceScrollView[thisView] = scrollview;
+ AddViewToRootContainer(AiVoiceScrollView[thisView]);
+ }
+
+ return true;
+ }
+
+ /*切换到聆听中界面*/
+ bool AiVoiceView::ChangeAiVoicListeningView(int16_t thisView)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoicListeningView");
+ if (AiVoiceScrollView[thisView] == nullptr)
+ {
+ p_AivoiceListeningView = new AivoiceListeningView();
+ if (p_AivoiceListeningView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ // AiVoiceScrollView[thisView] = p_AivoiceListeningView->CreateAivoiceListeningView();
+ UIScrollView *scrollview = p_AivoiceListeningView->CreateAivoiceListeningView();
+ if (scrollview == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ AiVoiceScrollView[thisView] = scrollview;
+ AddViewToRootContainer(AiVoiceScrollView[thisView]);
+ }
+ if (p_AivoiceListeningView)
+ {
+ p_AivoiceListeningView->GetShowtimeoutLabel()->SetText("10");
+ p_AivoiceListeningView->GetShowtimeoutLabel()->Invalidate();
+ }
+ AiVoiceModel::GetInstance().start_listening_timer();
+ return true;
+ }
+
+ /*切换到思考中界面*/
+ bool AiVoiceView::ChangeAiVoicThinkingView(int16_t thisView)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoicThinkingView");
+ if (AiVoiceScrollView[thisView] == nullptr)
+ {
+ p_AivoiceThinkingView = new AivoiceThinkingView();
+ if (p_AivoiceThinkingView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ // AiVoiceScrollView[thisView] = p_AivoiceThinkingView->CreateAivoiceThinkingView();
+ UIScrollView *scrollview = p_AivoiceThinkingView->CreateAivoiceThinkingView();
+ if (scrollview == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ AiVoiceScrollView[thisView] = scrollview;
+ AddViewToRootContainer(AiVoiceScrollView[thisView]);
+ }
+ return true;
+ }
+
+ /*切换到返回结果文本界面*/
+ bool AiVoiceView::ChangeAiVoicReturnResultTextView(int16_t thisView)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoicReturnResultTextView");
+ if (AiVoiceScrollView[thisView] == nullptr)
+ {
+ p_AivoiceReturnResultTextView = new AivoiceReturnResultTextView();
+ if (p_AivoiceReturnResultTextView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ // AiVoiceScrollView[thisView] = p_AivoiceReturnResultTextView->CreateAivoiceReturnResultTextView();
+ UIScrollView *scrollview = p_AivoiceReturnResultTextView->CreateAivoiceReturnResultTextView();
+ if (scrollview == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ AiVoiceScrollView[thisView] = scrollview;
+ AddViewToRootContainer(AiVoiceScrollView[thisView]);
+ }
+ return true;
+ }
+
+ /*切换到setapikeys界面*/
+ bool AiVoiceView::ChangeAiVoicSetApiKeysView(int16_t thisView)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoicSetApiKeysView");
+ if (AiVoiceScrollView[thisView] == nullptr)
+ {
+ p_SetApiKeysView = new SetApiKeysView();
+ if (p_SetApiKeysView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ // AiVoiceScrollView[thisView] = p_SetApiKeysView->CreateSetApiKeysView();
+ UIScrollView *scrollview = p_SetApiKeysView->CreateSetApiKeysView();
+ if (scrollview == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ AiVoiceScrollView[thisView] = scrollview;
+ AddViewToRootContainer(AiVoiceScrollView[thisView]);
+ }
+ return true;
+ }
+
+ /*切换到notsetapikeys界面*/
+ bool AiVoiceView::ChangeAiVoicNotSetApiKeysView(int16_t thisView)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoicNotSetApiKeysView");
+ if (AiVoiceScrollView[thisView] == nullptr)
+ {
+ p_NotSetApiKeysView = new NotSetApiKeysView();
+ if (p_NotSetApiKeysView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ // AiVoiceScrollView[thisView] = p_NotSetApiKeysView->CreateNotSetApiKeysView();
+ UIScrollView *scrollview = p_NotSetApiKeysView->CreateNotSetApiKeysView();
+ if (scrollview == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ AiVoiceScrollView[thisView] = scrollview;
+ AddViewToRootContainer(AiVoiceScrollView[thisView]);
+ }
+ return true;
+ }
+
+ /*切换到apikeys删除界面*/
+ bool AiVoiceView::ChangeAiVoicApiKeysDeleteView(int16_t thisView)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoicApiKeysDeleteView");
+ if (AiVoiceScrollView[thisView] == nullptr)
+ {
+ p_ApiKeysDeleteView = new ApiKeysDeleteView();
+ if (p_ApiKeysDeleteView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ // AiVoiceScrollView[thisView] = p_ApiKeysDeleteView->CreateApiKeysDeleteView();
+ UIScrollView *scrollview = p_ApiKeysDeleteView->CreateApiKeysDeleteView();
+ if (scrollview == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ AiVoiceScrollView[thisView] = scrollview;
+ AddViewToRootContainer(AiVoiceScrollView[thisView]);
+ }
+ return true;
+ }
+
+ /*切换到AI正在连接中视图*/
+ bool AiVoiceView::ChangeAiVoicConnectingView(int16_t thisView)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiVoicConnectingView");
+ if (AiVoiceScrollView[thisView] == nullptr)
+ {
+ p_AiVoiceConnectingView = new AiVoiceConnectingView();
+ if (p_AiVoiceConnectingView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ // AiVoiceScrollView[thisView] = p_AiVoiceConnectingView->CreateAiVoiceConnectingView();
+ UIScrollView *scrollview = p_AiVoiceConnectingView->CreateAiVoiceConnectingView();
+ if (scrollview == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
+ return false;
+ }
+ AiVoiceScrollView[thisView] = scrollview;
+ AddViewToRootContainer(AiVoiceScrollView[thisView]);
+ }
+ return true;
+ }
+
+ struct AiVoiceViewMapper
+ {
+ const int16_t viewId;
+ bool (AiVoiceView::*func)(int16_t thisView);
+ };
+
+ static const AiVoiceViewMapper ViewMapper[] = {
+ {AIVOICE_STARTCHAT_VIEWID, &AiVoiceView::ChangeAiVoiceStartChatView},
+ {AIVOICE_ALERT_APPBLUETOOTH_AND_4GNETWORK_VIEWID, &AiVoiceView::ChangeAiVoiceBluetoothFailedStartView},
+ {AIVOICE_AIMODEL_CONNECT_FAILED_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},
+ {AIVOICE_SETAPIKEYS, &AiVoiceView::ChangeAiVoicSetApiKeysView},
+ {AIVOICE_NOTSETAPIKEYS, &AiVoiceView::ChangeAiVoicNotSetApiKeysView},
+ {AIVOICE_APIKEYS_DELETE, &AiVoiceView::ChangeAiVoicApiKeysDeleteView},
+ {AIVOICE_AIMODE_CONNECTING, &AiVoiceView::ChangeAiVoicConnectingView},
+ };
+
+ 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)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ClickFunc err.");
+ return false;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool AiVoiceView::CheckViewParam(int16_t hideView, int16_t showView)
+ {
+ if (showView < 0 || showView >= MAX_AIVOICE_VIEWID)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::CheckViewParam showView err.");
+ return false;
+ }
+
+ if (hideView < 0 || hideView >= MAX_AIVOICE_VIEWID)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::CheckViewParam hideView err.");
+ return false;
+ }
+
+ return true;
+ }
+
+ static const int16 AiVoiceDestroyMapper[] = {
+ AIVOICE_AIMODE_CONNECTING,
+ };
+
+ void AiVoiceView::DestroyTempView(int16_t hideView)
+ {
+ int viewSize = sizeof(AiVoiceDestroyMapper) / sizeof(AiVoiceDestroyMapper[0]);
+ for (int i = 0; i < viewSize; i++)
+ {
+ if (hideView == AiVoiceDestroyMapper[i])
+ {
+ if (AiVoiceScrollView[hideView] != nullptr)
+ {
+ GetRootContainer()->Remove(AiVoiceScrollView[hideView]);
+ AiVoiceScrollView[hideView] = nullptr;
+ }
+ break;
+ }
+ }
+ switch (hideView)
+ {
+ case AIVOICE_AIMODE_CONNECTING:
+ if (p_AiVoiceConnectingView)
+ {
+ delete p_AiVoiceConnectingView;
+ p_AiVoiceConnectingView = nullptr;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ void AiVoiceView::ChangeView(int16_t hideView, int16_t showView)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeView");
+ if (!CheckViewParam(hideView, showView))
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::CheckViewParam failed.");
+ return;
+ }
+ AiVoiceScrollView[hideView]->SetVisible(false);
+ ClickFunc(showView);
+ AiVoiceScrollView[showView]->SetVisible(true);
+ if (AiVoiceScrollView[showView] != nullptr)
+ {
+ AiVoiceScrollView[showView]->SetVisible(true);
+ }
+ else
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceScrollView[%d] is nullptr", showView);
+ }
+ Draw();
+ DestroyTempView(hideView);
+ AiVoiceModel::GetInstance().SetCurView(showView);
+ return;
+ }
+
+ UIScrollView *AiVoiceView::GetAiVoiceScrollView(int16_t index)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::GetAiVoiceScrollView");
+ if (index >= 0 && index < MAX_AIVOICE_VIEWID)
+ {
+ return AiVoiceScrollView[index];
+ }
+ else
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Overstep ones bounds");
+ return nullptr;
+ }
+ }
+
+ void AiVoiceView::SetAiVoiceViewAllComponentsVisibilityStatus(void)
+ {
+ bool isAiModeChatGpt = (AiVoiceModel::GetInstance().GetAiModelTextId() == STR_AIMODES_CHATGPT);
+
+ SetComponentVisibility(chatButton, isAiModeChatGpt);
+ // SetComponentVisibility(chatLabel, isAiModeChatGpt);
+ // SetComponentVisibility(apiKeysButton, isAiModeChatGpt);
+ // SetComponentVisibility(apiKeysLabel, isAiModeChatGpt);
+ // SetComponentVisibility(upImage, isAiModeChatGpt);
+
+ // SetComponentVisibility(startChatLabel, !isAiModeChatGpt);
+ SetComponentVisibility(startChatButton, !isAiModeChatGpt);
+ }
+
+ void AiVoiceView::SetComponentVisibility(UIView *component, bool isVisible)
+ {
+ if (component)
+ {
+ component->SetVisible(isVisible);
+ }
+ }
+
+ void AiVoiceView::ChangeAiModelAndUpdateComponentsStatus(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeAiModelAndUpdateComponentsStatus");
+ int textId = AiVoiceModel::GetInstance().GetAiModelTextId();
+ if (title)
+ {
+ if(textId == STR_DEEPSEEK)
+ {
+ title->SetText("DeepSeek");
+ }
+ else
+ {
+ title->SetTextId(textId);
+ title->ForceResetText();
+ }
+ }
+ if (aiModelImage)
+ {
+ auto it = TextIdToImagePath.find(textId);
+ if (it != TextIdToImagePath.end())
+ {
+ aiModelImage->SetSrc(it->second);
+ aiModelImage->Invalidate();
+ }
+ }
+
+ SetAiVoiceViewAllComponentsVisibilityStatus();
+
+ /*更新title的textid*/
+ if (p_AiVoiceBluetoothFailedStartView)
+ {
+ p_AiVoiceBluetoothFailedStartView->UpdateTitleTextId(textId);
+ }
+ if (p_AivoiceReturnResultTextView)
+ {
+ p_AivoiceReturnResultTextView->UpdateTitleTextId(textId);
+ }
+ if (p_AivoiceMobileDataFailedStartView)
+ {
+ p_AivoiceMobileDataFailedStartView->UpdateTitleTextId(textId);
+ }
+ if (p_AivoiceConnectTimeoutView)
+ {
+ p_AivoiceConnectTimeoutView->UpdateTitleTextId(textId);
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-03-28 14:27:05
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-10-19 17:16:50
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/language/src/AivoiceChatContentListAdapter.cpp
+ */
+#include "aivoice/include/AivoiceChatContentListAdapter.h"
+#include "wearable_log.h"
+#include <UiConfig.h>
+
+namespace OHOS
+{
+
+ AivoiceChatContentListAdapter::AivoiceChatContentListAdapter()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceChatContentListAdapter::AivoiceChatContentListAdapter");
+ }
+
+ AivoiceChatContentListAdapter::~AivoiceChatContentListAdapter()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceChatContentListAdapter::~AivoiceChatContentListAdapter");
+ listData.clear();
+ }
+
+ uint16_t AivoiceChatContentListAdapter::GetCount(void)
+ {
+ return listData.size();
+ }
+
+ std::list<ChatContentItem> &AivoiceChatContentListAdapter::GetChatContentItem()
+ {
+ return listData;
+ }
+
+ void AivoiceChatContentListAdapter::SetData(std::list<ChatContentItem> &data)
+ {
+ if (!listData.empty())
+ {
+ listData.clear();
+ }
+ std::list<ChatContentItem>::iterator it;
+ for (it = data.begin(); it != data.end(); it++)
+ {
+ listData.push_back(*it);
+ }
+ }
+
+ void AivoiceChatContentListAdapter::ClearData(void)
+ {
+ if (!listData.empty())
+ {
+ listData.clear();
+ }
+ }
+
+ void AivoiceChatContentListAdapter::calculateChatContentItemViewHeight(std::string text, bool flag)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceChatContentListAdapter::calculateChatContentItemViewHeight");
+
+ const char *Text = text.c_str();
+ aiAnswerFlag = flag;
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Text = %s,aiAnswerFlag = %d\n", Text, aiAnswerFlag);
+
+ UILabel label;
+ label.SetPosition(53, 100);
+ label.Resize(aiAnswerFlag ? 280 : 200, 60);
+ label.SetStyle(STYLE_TEXT_FONT, 26);
+ label.SetStyle(STYLE_LINE_HEIGHT, 30);
+ label.SetText(Text);
+ label.SetLineBreakMode(UILabel::LINE_BREAK_WRAP);
+ label.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ label.SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, 26);
+
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "label.GetHeight = %d,label.GetTextHeight = %d\n", label.GetHeight(), label.GetTextHeight());
+ itemViewHeight = label.GetTextHeight();
+ }
+
+ UIView *AivoiceChatContentListAdapter::GetView(UIView *inView, int16_t index)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceChatContentListAdapter::GetView,index %d", index);
+ // 1.先检查列表数据是否为空,若为空则返回空指针
+ if (listData.empty())
+ {
+ return nullptr;
+ }
+ // 2.接着检查索引是否小于0,若小于0则返回空指针
+ if (index < 0)
+ {
+ return nullptr;
+ }
+ // 3.检查是否超出列表数据大小,若超出则返回空指针
+ size_t uindex = index;
+ if (uindex >= listData.size())
+ {
+ return nullptr;
+ }
+ // 4.通过迭代器访问列表中指定索引位置的元素,将其赋值给itemData变量
+ std::list<ChatContentItem>::iterator it = listData.begin();
+ for (int i = 0; i < index; i++)
+ {
+ it++;
+ }
+ ChatContentItem itemData = *it;
+ AivoiceChatContentListItemView *item = nullptr;
+ /* -------------------------------------------------------------------------- */
+ calculateChatContentItemViewHeight(itemData.text, itemData.isAiAnswer);
+ /* -------------------------------------------------------------------------- */
+ // 5.根据传入的inView参数是否已经存在一个视图对象,若为空则创建一个新的LanguageSwitchListItemView对象,否则将inView转换成LanguageSwitchListItemView类型的指针
+ if (inView == nullptr)
+ {
+ item = new AivoiceChatContentListItemView(itemViewHeight, aiAnswerFlag);
+ }
+ else
+ {
+ item = dynamic_cast<AivoiceChatContentListItemView *>(inView);
+ item->ResetItemView(itemViewHeight, aiAnswerFlag);
+ }
+ item->SetViewIndex(index);
+ item->SetItemInfo(itemData);
+ return item;
+ }
+
+ void AivoiceChatContentListAdapter::SetItemClickListener(UIView::OnClickListener *itemclicklistener)
+ {
+ itemClickListener = itemclicklistener;
+ }
+
+ void AivoiceChatContentListAdapter::AddListItem(const ChatContentItem &item)
+ {
+ listData.push_back(item);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-29 17:27:25
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2025-03-19 10:12:45
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AivoiceChatContentListItemView.cpp
+ */
+
+#include "aivoice/include/AivoiceChatContentListItemView.h"
+#include "aivoice/include/AiVoiceModel.h"
+#include "wearable_log.h"
+
+namespace OHOS
+{
+
+ static constexpr const int16_t ITEM_VIEW_X = 0; /*itemview x坐标*/
+ static constexpr const int16_t ITEM_VIEW_Y = 0; /*itemview y坐标*/
+ static constexpr const int16_t ITEM_VIEW_W = 360; /*itemview 宽*/
+ static constexpr const int16_t ITEM_VIEW_H = 80; /*itemview 高*/
+
+ static constexpr const int16_t CHATCONTENTLABEL_X = 40;
+ static constexpr const int16_t CHATCONTENTLABEL_Y = 25;
+ static constexpr const int16_t CHATCONTENTLABEL_TEXT_FONT = 26;
+ static constexpr const int16_t CHATCONTENTLABEL_LINE_HEIGHT = 30;
+
+ static constexpr const int64_t RADIUS = 20;
+
+ static constexpr const int16_t QUESTION_CHATCONTENTIMAGE_X = 0;
+ static constexpr const int16_t ANSWER_CHATCONTENTIMAGE_X = 289;
+
+ static constexpr const int16_t QUESTION_CHATCONTENTSCROLLVIEW_X = 20;
+ static constexpr const int16_t ANSWER_CHATCONTENTSCROLLVIEW_X = 59;
+
+ static constexpr const int16_t QUESTION_CHATCONTENTSCROLLVIEW_W = 340;
+ static constexpr const int16_t ANSWER_CHATCONTENTSCROLLVIEW_W = 280;
+
+ static constexpr const int16_t QUESTION_CHATCONTENTLABEL_W = 280;
+ static constexpr const int16_t ANSWER_CHATCONTENTLABEL_W = 200;
+
+ static constexpr const char *QUESTION_ITEM_IMAGE_SRC = "/user/res/AIVoice/AI_RecGreen.bin";
+ static constexpr const char *ANSWER_ITEM_IMAGE_SRC = "/user/res/AIVoice/AI_RecBlack.bin";
+
+ static constexpr const int64_t QUESTION_ITEM_VIEW_COLOR = 0xff4fc34c; /*0xff4fc34c*/
+ static constexpr const int64_t ANSWER_ITEM_VIEW_COLOR = 0xff191919; /*0xff191919*/
+
+ AivoiceChatContentListItemView::AivoiceChatContentListItemView(int viewHeight, bool isAiAnswerFlag)
+ : m_viewHeight(viewHeight), m_isAiAnswerFalg(isAiAnswerFlag)
+ {
+ SetPosition(ITEM_VIEW_X, ITEM_VIEW_Y);
+ Resize(ITEM_VIEW_W, m_viewHeight + ITEM_VIEW_H);
+ SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);
+ SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+ SetTouchable(true);
+ SetUpChild();
+ Add(&chatContentImage);
+ chatContentScrollView.Add(&chatContentLabel);
+ Add(&chatContentScrollView);
+ }
+
+ AivoiceChatContentListItemView::~AivoiceChatContentListItemView()
+ {
+ Remove(&chatContentImage);
+ chatContentScrollView.Remove(&chatContentLabel);
+ Remove(&chatContentScrollView);
+ }
+
+ void AivoiceChatContentListItemView::SetItemInfo(const ChatContentItem &itemInfo)
+ {
+ chatContentLabel.SetText(itemInfo.text.c_str());
+ }
+
+ void AivoiceChatContentListItemView::ResetItemView(int viewHeight, bool isAiAnswerFlag)
+ {
+ if (viewHeight < 120 * CHATCONTENTLABEL_LINE_HEIGHT + 30) // itemView最高为120 * label行高
+ Resize(ITEM_VIEW_W, viewHeight + ITEM_VIEW_H);
+
+ chatContentImage.SetPosition(isAiAnswerFlag ? QUESTION_CHATCONTENTIMAGE_X : ANSWER_CHATCONTENTIMAGE_X, 0, 70, 30);
+ chatContentImage.SetSrc(isAiAnswerFlag ? ANSWER_ITEM_IMAGE_SRC : QUESTION_ITEM_IMAGE_SRC);
+
+ chatContentScrollView.SetPosition(isAiAnswerFlag ? QUESTION_CHATCONTENTSCROLLVIEW_X : ANSWER_CHATCONTENTSCROLLVIEW_X, 0);
+ if (viewHeight < 120 * CHATCONTENTLABEL_LINE_HEIGHT + 30) // scrollviewView最高为120 * label行高
+ chatContentScrollView.Resize(isAiAnswerFlag ? QUESTION_CHATCONTENTSCROLLVIEW_W : ANSWER_CHATCONTENTSCROLLVIEW_W, GetHeight() - 30);
+ chatContentScrollView.SetStyle(STYLE_BACKGROUND_COLOR, isAiAnswerFlag ? ANSWER_ITEM_VIEW_COLOR : QUESTION_ITEM_VIEW_COLOR);
+
+ if (viewHeight < 120 * CHATCONTENTLABEL_LINE_HEIGHT) // label最高为120 * label行高
+ {
+ chatContentLabel.Resize(isAiAnswerFlag ? QUESTION_CHATCONTENTLABEL_W : ANSWER_CHATCONTENTLABEL_W, viewHeight);
+ }
+ else
+ {
+ if(!AiVoiceModel::GetInstance().GetIsLimitDisplayed())
+ {
+ AiVoiceModel::GetInstance().SetIsLimitDisplayed(true);
+ chatContentLabel.SetLineBreakMode(isAiAnswerFlag ? UILabel::LINE_BREAK_ELLIPSIS : UILabel::LINE_BREAK_WRAP);//超过高度在末尾用省略号替换
+ }
+ }
+ }
+
+ void AivoiceChatContentListItemView::SetUpChild()
+ {
+ chatContentImage.SetPosition(m_isAiAnswerFalg ? QUESTION_CHATCONTENTIMAGE_X : ANSWER_CHATCONTENTIMAGE_X, 0, 70, 30);
+ chatContentImage.SetSrc(m_isAiAnswerFalg ? ANSWER_ITEM_IMAGE_SRC : QUESTION_ITEM_IMAGE_SRC);
+
+ chatContentScrollView.SetPosition(m_isAiAnswerFalg ? QUESTION_CHATCONTENTSCROLLVIEW_X : ANSWER_CHATCONTENTSCROLLVIEW_X, 0);
+ chatContentScrollView.Resize(m_isAiAnswerFalg ? QUESTION_CHATCONTENTSCROLLVIEW_W : ANSWER_CHATCONTENTSCROLLVIEW_W, GetHeight() - 30);
+ chatContentScrollView.SetStyle(STYLE_BACKGROUND_COLOR, m_isAiAnswerFalg ? ANSWER_ITEM_VIEW_COLOR : QUESTION_ITEM_VIEW_COLOR);
+ chatContentScrollView.SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+ chatContentScrollView.SetStyle(STYLE_BORDER_RADIUS, RADIUS);
+ chatContentScrollView.SetTouchable(false);
+
+ chatContentLabel.SetPosition(CHATCONTENTLABEL_X, CHATCONTENTLABEL_Y);
+ chatContentLabel.Resize(m_isAiAnswerFalg ? QUESTION_CHATCONTENTLABEL_W : ANSWER_CHATCONTENTLABEL_W, m_viewHeight);
+ chatContentLabel.SetStyle(STYLE_TEXT_FONT, CHATCONTENTLABEL_TEXT_FONT);
+ chatContentLabel.SetStyle(STYLE_LINE_HEIGHT, CHATCONTENTLABEL_LINE_HEIGHT);
+ chatContentLabel.SetLineBreakMode(UILabel::LINE_BREAK_WRAP);
+ chatContentLabel.SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER);
+ chatContentLabel.SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, CHATCONTENTLABEL_TEXT_FONT);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-05-07 11:25:58
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-11-14 17:29:47
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/AiVoice/src/AivoiceConnectTimeoutView.cpp
+ */
+#include "aivoice/include/AiVoicePresenter.h"
+#include "aivoice/include/AivoiceConnectTimeoutView.h"
+#include "aivoice/include/AiVoiceModel.h"
+#include "wearable_log.h"
+#include "ui_resource_string.h"
+#include <UiConfig.h>
+namespace OHOS
+{
+ static constexpr const int16_t LABEL_ROLL_SPEED = 70;
+
+ static AivoiceConnectTimeoutView *g_pAivoiceConnectTimeoutView{nullptr};
+
+ AivoiceConnectTimeoutView::AivoiceConnectTimeoutView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::AivoiceConnectTimeoutView");
+ g_pAivoiceConnectTimeoutView = this;
+ }
+
+ AivoiceConnectTimeoutView::~AivoiceConnectTimeoutView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::~AivoiceConnectTimeoutView");
+ ClearAll();
+ g_pAivoiceConnectTimeoutView = nullptr;
+ }
+
+ AivoiceConnectTimeoutView *AivoiceConnectTimeoutView::GetInstance()
+ {
+ return g_pAivoiceConnectTimeoutView;
+ }
+
+ void AivoiceConnectTimeoutView::ClearAll(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::ClearAll");
+ if (scrollView != nullptr)
+ {
+ scrollView->RemoveAll();
+ if (title != nullptr)
+ {
+ delete title;
+ title = nullptr;
+ }
+ if (attentionImage != nullptr)
+ {
+ delete attentionImage;
+ attentionImage = nullptr;
+ }
+ if (NoteLabel != nullptr)
+ {
+ delete NoteLabel;
+ NoteLabel = nullptr;
+ }
+ if (ensure != nullptr)
+ {
+ delete ensure;
+ ensure = nullptr;
+ }
+ if (ensureButton != nullptr)
+ {
+ delete ensureButton;
+ ensureButton = nullptr;
+ }
+ delete scrollView;
+ scrollView = nullptr;
+ }
+ }
+
+ UILabelExt *AivoiceConnectTimeoutView::AivoiceConnectTimeoutLabelInit(LabelConfig &labelconfig)
+ {
+ UILabelExt *label = new UILabelExt();
+ if (label == nullptr)
+ {
+ return nullptr;
+ }
+ label->SetPosition(labelconfig.left, labelconfig.top, labelconfig.width, labelconfig.height);
+ label->SetStyle(STYLE_TEXT_FONT, labelconfig.fontSize);
+ label->SetStyle(STYLE_LINE_HEIGHT, labelconfig.lineHeigh);
+ //TOOD: 待优化
+ if(labelconfig.textId == STR_DEEPSEEK) {
+ label->SetText("DeepSeek");
+ } else
+ label->SetTextId(labelconfig.textId);
+ label->SetLineBreakMode(labelconfig.lineBreakMode);
+ label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize);
+ label->SetRollSpeed(LABEL_ROLL_SPEED);
+ return label;
+ }
+
+ UIButton *AivoiceConnectTimeoutView::AivoiceConnectTimeoutButtonInit(ButtonConfig &buttonconfig)
+ {
+ UIButton *button = new UIButton();
+ if (button == nullptr)
+ {
+ return nullptr;
+ }
+ button->SetPosition(buttonconfig.x, buttonconfig.y, buttonconfig.w, buttonconfig.h);
+ button->SetViewId(buttonconfig.ViewId);
+ button->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919);
+ button->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+ button->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff383838, UIButton::PRESSED);
+
+ return button;
+ }
+
+ UIImageView *AivoiceConnectTimeoutView::AivoiceConnectTimeoutImageInit(ImageConfig &imageconfig)
+ {
+ UIImageView *Image = new UIImageView();
+ if (Image == nullptr)
+ {
+ return nullptr;
+ }
+ Image->SetPosition(imageconfig.x, imageconfig.y, imageconfig.w, imageconfig.h);
+ return Image;
+ }
+
+ bool AivoiceConnectTimeoutView::CreateAivoiceConnectTimeoutScrollView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::CreateAivoiceConnectTimeoutScrollView");
+ scrollView = new UIScrollView();
+ if (scrollView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::scrollView new fail!");
+ return false;
+ }
+ UIView::OnDragListener *dragListener = static_cast<UIView::OnDragListener *>(AiVoicePresenter::GetInstance());
+ if (dragListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::dragListener new fail!");
+ return false;
+ }
+ scrollView->SetOnDragListener(dragListener);
+ scrollView->SetPosition(0, 0, 466, 466);
+ scrollView->SetTouchable(true);
+ scrollView->SetDraggable(true);
+
+ return true;
+ }
+
+ bool AivoiceConnectTimeoutView::CreateAivoiceConnectTimeoutLabel(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::CreateAivoiceConnectTimeoutLabel");
+ LabelConfig labelconfig = {
+ .left = 83,
+ .top = 50,
+ .width = 300,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = AiVoiceModel::GetInstance().GetAiModelTextId(),
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ title = AivoiceConnectTimeoutLabelInit(labelconfig);
+ if (title == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::title is nullptr!");
+ return false;
+ }
+ /* -------------------------------------------------------------------------- */
+ NoteLabel = new UILabelExt();
+ if (NoteLabel == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "NoteLabel is nullptr!");
+ return false;
+ }
+ NoteLabel->SetPosition(53, 222, 360, 70);
+ NoteLabel->SetStyle(STYLE_TEXT_FONT, 30);
+ NoteLabel->SetStyle(STYLE_LINE_HEIGHT, 35);
+ NoteLabel->SetLineBreakMode(UILabel::LINE_BREAK_OSCILLATION);
+ NoteLabel->SetRollSpeed(23);
+ NoteLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ NoteLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, 30);
+ /* -------------------------------------------------------------------------- */
+ labelconfig = {
+ .left = 133,
+ .top = 368,
+ .width = 200,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = STR_OK,
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ ensure = AivoiceConnectTimeoutLabelInit(labelconfig);
+ if (ensure == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::ensure is nullptr!");
+ return false;
+ }
+
+ return true;
+ }
+
+ bool AivoiceConnectTimeoutView::CreateAivoiceConnectTimeoutButton(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::CreateAivoiceConnectTimeoutButton");
+ ButtonConfig buttonconfig = {
+ .x = 93,
+ .y = 340,
+ .w = 280,
+ .h = 90,
+ .ViewId = AIVOICECONNECTTIMEOUT_ENSURE_BUTTON_VIEW_ID,
+ };
+ ensureButton = AivoiceConnectTimeoutButtonInit(buttonconfig);
+ if (ensureButton == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ensureButton new fail!");
+ return false;
+ }
+ UIView::OnTouchListener *touchListener = static_cast<UIView::OnTouchListener *>(AiVoicePresenter::GetInstance());
+ if (touchListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::touchListener can not be nullptr!");
+ return false;
+ }
+ ensureButton->SetOnTouchListener(touchListener);
+
+ return true;
+ }
+
+ bool AivoiceConnectTimeoutView::CreateAivoiceConnectTimeoutImage(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::CreateAivoiceConnectTimeoutImage");
+ ImageConfig imageconfig = {
+ .x = 193,
+ .y = 120,
+ .w = 80,
+ .h = 80,
+ };
+ attentionImage = AivoiceConnectTimeoutImageInit(imageconfig);
+ if (attentionImage == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "attentionImage new fail!");
+ return false;
+ }
+ attentionImage->SetStyle(STYLE_BORDER_RADIUS, 100);
+ attentionImage->SetSrc(PNG_ATTENTION_IMAGE);
+
+ return true;
+ }
+
+ UIScrollView *AivoiceConnectTimeoutView::CreateAivoiceConnectTimeoutView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::CreateAivoiceConnectTimeoutView");
+ if (scrollView == nullptr)
+ {
+ if (!CreateAivoiceConnectTimeoutScrollView() || !CreateAivoiceConnectTimeoutLabel() ||
+ !CreateAivoiceConnectTimeoutButton() || !CreateAivoiceConnectTimeoutImage())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::CreateAivoiceConnectTimeoutView fail!!");
+ return nullptr;
+ }
+ scrollView->Add(title);
+ scrollView->Add(attentionImage);
+ scrollView->Add(NoteLabel);
+ scrollView->Add(ensureButton);
+ scrollView->Add(ensure);
+ }
+ return scrollView;
+ }
+
+ void AivoiceConnectTimeoutView::UpdateTitleTextId(int textId)
+ {
+ if (title)
+ {
+ if(textId == STR_DEEPSEEK)
+ {
+ title->SetText("DeepSeek");
+ }
+ else
+ {
+ title->SetTextId(textId);
+ title->ForceResetText();
+ }
+ }
+ }
+
+ // 更新错误信息内容
+ void AivoiceConnectTimeoutView::UpdateNoteText()
+ {
+ if (NoteLabel)
+ {
+ // NoteLabel->SetText("");
+ std::string text = AiVoiceModel::GetInstance().GetErrnote();
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "text = %s", text.c_str());
+ NoteLabel->SetText(text.c_str());
+ NoteLabel->SetLineBreakMode(UILabel::LINE_BREAK_OSCILLATION);
+ NoteLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ NoteLabel->Invalidate();
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-05-07 11:25:58
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-11-05 11:09:40
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/AiVoice/src/AivoiceListeningView.cpp
+ */
+#include "aivoice/include/AiVoicePresenter.h"
+#include "aivoice/include/AivoiceListeningView.h"
+#include "wearable_log.h"
+#include "ui_resource_string.h"
+#include <UiConfig.h>
+#include "uicomponents/UIComponents.h"
+// #include "common/image_cache_manager.h"
+namespace OHOS
+{
+
+ static AivoiceListeningView *g_pAivoiceListeningView{nullptr};
+
+ AivoiceListeningView::AivoiceListeningView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::AivoiceListeningView");
+ g_pAivoiceListeningView = this;
+ }
+
+ AivoiceListeningView::~AivoiceListeningView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::~AivoiceListeningView");
+ ClearAll();
+ g_pAivoiceListeningView = nullptr;
+ }
+
+ AivoiceListeningView *AivoiceListeningView::GetInstance()
+ {
+ return g_pAivoiceListeningView;
+ }
+
+ void AivoiceListeningView::ClearAll(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::ClearAll");
+ if (scrollView != nullptr)
+ {
+ scrollView->RemoveAll();
+
+ if (title != nullptr)
+ {
+ delete title;
+ title = nullptr;
+ }
+
+ if (AiVoiceListeningImageAnimatorView != nullptr)
+ {
+ AiVoiceListeningImageAnimatorView->Stop();
+ delete AiVoiceListeningImageAnimatorView;
+ AiVoiceListeningImageAnimatorView = nullptr;
+
+ FreeImageInfoArray(AiVoiceListeningPathsArray, AIVoiceListeningImagePaths, AIVOICE_LISTENING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES);
+ }
+
+ if (showtimeout != nullptr)
+ {
+ delete showtimeout;
+ showtimeout = nullptr;
+ }
+
+ if (finishSpeak != nullptr)
+ {
+ delete finishSpeak;
+ finishSpeak = nullptr;
+ }
+
+ if (finishSpeakButton != nullptr)
+ {
+ delete finishSpeakButton;
+ finishSpeakButton = nullptr;
+ }
+
+ delete scrollView;
+ scrollView = nullptr;
+ }
+ }
+
+ UILabelExt *AivoiceListeningView::AivoiceListeningLabelInit(LabelConfig &labelconfig)
+ {
+ UILabelExt *label = new UILabelExt();
+ if (label == nullptr)
+ {
+ return nullptr;
+ }
+ label->SetPosition(labelconfig.left, labelconfig.top, labelconfig.width, labelconfig.height);
+ label->SetStyle(STYLE_TEXT_FONT, labelconfig.fontSize);
+ label->SetStyle(STYLE_LINE_HEIGHT, labelconfig.lineHeigh);
+ label->SetTextId(labelconfig.textId);
+ label->SetLineBreakMode(labelconfig.lineBreakMode);
+ label->SetRollSpeed(23);
+ label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize);
+ return label;
+ }
+
+ UIButton *AivoiceListeningView::AivoiceListeningButtonInit(ButtonConfig &buttonconfig)
+ {
+ UIButton *button = new UIButton();
+ if (button == nullptr)
+ {
+ return nullptr;
+ }
+ button->SetPosition(buttonconfig.x, buttonconfig.y, buttonconfig.w, buttonconfig.h);
+ button->SetViewId(buttonconfig.ViewId);
+ button->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919);
+ button->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+ button->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff383838, UIButton::PRESSED);
+
+ return button;
+ }
+
+ UIImageAnimatorView *AivoiceListeningView::AivoiceListeningImageAnimatorInit(ImageAnimatorConfig &imageanimatorconfig)
+ {
+ UIImageAnimatorView *animatorView = new UIImageAnimatorView();
+ if (animatorView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceListeningImageAnimatorView::AiVoiceListeningImageAnimatorView new fail");
+ return nullptr;
+ }
+
+ for (uint8_t i = 0; i < imageanimatorconfig.numFrames; i++)
+ {
+ imageanimatorconfig.imageInfoArray[i].imageInfo = imageanimatorconfig.pathsArray[i];
+ // imageanimatorconfig.imageInfoArray[i].imagePath = (imageanimatorconfig.pathsArray[i]);
+ // imageanimatorconfig.imageInfoArray[i].imageType = IMG_SRC_FILE_PATH;
+ imageanimatorconfig.imageInfoArray[i].imageType = IMG_SRC_IMAGE_INFO;
+ imageanimatorconfig.imageInfoArray[i].pos.x = imageanimatorconfig.x;
+ imageanimatorconfig.imageInfoArray[i].pos.y = imageanimatorconfig.y;
+ imageanimatorconfig.imageInfoArray[i].width = imageanimatorconfig.width;
+ imageanimatorconfig.imageInfoArray[i].height = imageanimatorconfig.height;
+ }
+
+ animatorView->SetPosition(imageanimatorconfig.x, imageanimatorconfig.y, imageanimatorconfig.width, imageanimatorconfig.height);
+ animatorView->SetImageAnimatorSrc(imageanimatorconfig.imageInfoArray, imageanimatorconfig.numFrames, imageanimatorconfig.delay);
+ animatorView->SetRepeat(true);
+ animatorView->SetSizeFixed(true);
+ // animatorView->SetAutoEnable(false);
+ // animatorView->SetResizeMode(UIImageAnimatorView::FILL);
+ animatorView->Start();
+
+ return animatorView;
+ }
+
+ bool AivoiceListeningView::CreateAivoiceListeningScrollView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::CreateAivoiceListeningScrollView");
+ scrollView = new UIScrollView();
+ if (scrollView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::scrollView new fail!");
+ return false;
+ }
+ scrollView->SetPosition(0, 0, 466, 466);
+ UIView::OnDragListener *dragListener = static_cast<UIView::OnDragListener *>(AiVoicePresenter::GetInstance());
+ if (dragListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::dragListener new fail!");
+ return false;
+ }
+ scrollView->SetOnDragListener(dragListener);
+ scrollView->SetTouchable(true);
+ scrollView->SetDraggable(true);
+
+ return true;
+ }
+
+ bool AivoiceListeningView::CreateAivoiceListeningLabel(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::CreateAivoiceListeningLabel");
+ LabelConfig labelconfig = {
+ .left = 83,
+ .top = 50,
+ .width = 300,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = STR_LISTENING,
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ title = AivoiceListeningLabelInit(labelconfig);
+ if (title == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::title is nullptr!");
+ return false;
+ }
+ /* -------------------------------------------------------------------------- */
+ labelconfig = {
+ .left = 133,
+ .top = 368,
+ .width = 200,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = STR_FINISH_SPEAKING,
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ finishSpeak = AivoiceListeningLabelInit(labelconfig);
+ if (finishSpeak == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::finishSpeak is nullptr!");
+ return false;
+ }
+ /* -------------------------------------------------------------------------- */
+ showtimeout = new UILabelExt();
+ if (showtimeout == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::showtimeout is nullptr!");
+ return false;
+ }
+ showtimeout->SetPosition(60, 258, 240, 60);
+ showtimeout->SetStyle(STYLE_TEXT_FONT, 50);
+ showtimeout->SetStyle(STYLE_LINE_HEIGHT, 60);
+ showtimeout->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS);
+ showtimeout->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ showtimeout->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, 50);
+
+ return true;
+ }
+
+ bool AivoiceListeningView::CreateAivoiceListeningButton(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::CreateAivoiceListeningButton");
+ ButtonConfig buttonconfig = {
+ .x = 93,
+ .y = 340,
+ .w = 280,
+ .h = 90,
+ .ViewId = FINISH_SPEAKING_BUTTON_VIEW_ID,
+ };
+ finishSpeakButton = AivoiceListeningButtonInit(buttonconfig);
+ if (finishSpeakButton == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "finishSpeakButton new fail!");
+ return false;
+ }
+ UIView::OnTouchListener *touchListener = static_cast<UIView::OnTouchListener *>(AiVoicePresenter::GetInstance());
+ if (touchListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::touchListener can not be nullptr!");
+ return false;
+ }
+ finishSpeakButton->SetOnTouchListener(touchListener);
+
+ return true;
+ }
+
+ bool AivoiceListeningView::CreateAivoiceListeningImageAnimator(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::CreateAivoiceListeningImageAnimator");
+ AiVoiceListeningPathsArray = CreateImageInfoArray(AIVoiceListeningImagePaths, AIVOICE_LISTENING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES);
+ if (AiVoiceListeningPathsArray == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::AiVoiceListeningPathsArray is nullptr!!");
+ return false;
+ }
+
+ ImageAnimatorConfig imageanimatorconfig = {
+ .x = AIVOICE_LISTENING_IMAGE_ANIMATOR_VIEW_X,
+ .y = AIVOICE_LISTENING_IMAGE_ANIMATOR_VIEW_Y,
+ .width = AIVOICE_LISTENING_IMAGE_ANIMATOR_VIEW_W,
+ .height = AIVOICE_LISTENING_IMAGE_ANIMATOR_VIEW_H,
+ .imageInfoArray = AiVoiceListeningImageInfo,
+ .pathsArray = AiVoiceListeningPathsArray,
+ .numFrames = AIVOICE_LISTENING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES,
+ .delay = AIVOICE_LISTENING_IMAGE_ANIMATOR_DELAY,
+ };
+ AiVoiceListeningImageAnimatorView = AivoiceListeningImageAnimatorInit(imageanimatorconfig);
+ if (AiVoiceListeningImageAnimatorView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceListeningImageAnimatorView::AiVoiceListeningImageAnimatorView new fail");
+ return false;
+ }
+
+ return true;
+ }
+
+ UIScrollView *AivoiceListeningView::CreateAivoiceListeningView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::CreateAivoiceListeningView");
+#if 0
+ if (scrollView == nullptr)
+ {
+ if (!CreateAivoiceListeningScrollView() || !CreateAivoiceListeningLabel() ||
+ !CreateAivoiceListeningButton() || !CreateAivoiceListeningImageAnimator())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::CreateAivoiceListeningView fail!!");
+ return nullptr;
+ }
+ scrollView->Add(title);
+ scrollView->Add(AiVoiceListeningImageAnimatorView);
+ scrollView->Add(finishSpeakButton);
+ scrollView->Add(finishSpeak);
+ }
+#else
+ if (!CreateAivoiceListeningScrollView())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::CreateAivoiceListeningScrollView fail!!");
+ }
+ if (!CreateAivoiceListeningLabel())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::CreateAivoiceListeningLabel fail!!");
+ }
+ if (!CreateAivoiceListeningButton())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::CreateAivoiceListeningButton fail!!");
+ }
+ if (!CreateAivoiceListeningImageAnimator())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::CreateAivoiceListeningImageAnimator fail!!");
+ }
+ if (scrollView == nullptr)
+ {
+ return nullptr;
+ }
+ else
+ {
+ if (title)
+ {
+ scrollView->Add(title);
+ }
+ if (AiVoiceListeningImageAnimatorView)
+ {
+ scrollView->Add(AiVoiceListeningImageAnimatorView);
+ }
+ if (showtimeout)
+ {
+ showtimeout->SetX((scrollView->GetWidth() - showtimeout->GetWidth()) / 2);
+ scrollView->Add(showtimeout);
+ }
+ if (finishSpeakButton)
+ {
+ scrollView->Add(finishSpeakButton);
+ }
+ if (finishSpeak)
+ {
+ scrollView->Add(finishSpeak);
+ }
+ return scrollView;
+ }
+#endif
+ }
+
+ UILabelExt *AivoiceListeningView::GetShowtimeoutLabel(void)
+ {
+ return showtimeout;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-05-07 11:25:58
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2025-03-03 11:49:39
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/AiVoice/src/AivoiceMobileDataFailedStartView.cpp
+ */
+#include "aivoice/include/AiVoicePresenter.h"
+#include "aivoice/include/AivoiceMobileDataFailedStartView.h"
+#include "aivoice/include/AiVoiceModel.h"
+#include "wearable_log.h"
+#include "ui_resource_string.h"
+#include <UiConfig.h>
+namespace OHOS
+{
+
+ static AivoiceMobileDataFailedStartView *g_pAivoiceMobileDataFailedStartView{nullptr};
+
+ AivoiceMobileDataFailedStartView::AivoiceMobileDataFailedStartView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceMobileDataFailedStartView::AivoiceMobileDataFailedStartView");
+ g_pAivoiceMobileDataFailedStartView = this;
+ }
+
+ AivoiceMobileDataFailedStartView::~AivoiceMobileDataFailedStartView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceMobileDataFailedStartView::~AivoiceMobileDataFailedStartView");
+ ClearAll();
+ g_pAivoiceMobileDataFailedStartView = nullptr;
+ }
+
+ AivoiceMobileDataFailedStartView *AivoiceMobileDataFailedStartView::GetInstance()
+ {
+ return g_pAivoiceMobileDataFailedStartView;
+ }
+
+ void AivoiceMobileDataFailedStartView::ClearAll(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceMobileDataFailedStartView::ClearAll");
+ if (scrollView != nullptr)
+ {
+ scrollView->RemoveAll();
+
+ if (title != nullptr)
+ {
+ delete title;
+ title = nullptr;
+ }
+
+ if (attentionImage != nullptr)
+ {
+ delete attentionImage;
+ attentionImage = nullptr;
+ }
+
+ for (int i = 0; i < 2; i++)
+ {
+ if (label[i] != nullptr)
+ {
+ delete label[i];
+ label[i];
+ }
+ }
+
+ if (ensure != nullptr)
+ {
+ delete ensure;
+ ensure = nullptr;
+ }
+
+ if (ensureButton != nullptr)
+ {
+ delete ensureButton;
+ ensureButton = nullptr;
+ }
+
+ delete scrollView;
+ scrollView = nullptr;
+ }
+ }
+
+ UILabelExt *AivoiceMobileDataFailedStartView::AivoiceMobileDataFailedStartLabelInit(LabelConfig &labelconfig)
+ {
+ UILabelExt *label = new UILabelExt();
+ if (label == nullptr)
+ {
+ return nullptr;
+ }
+ label->SetPosition(labelconfig.left, labelconfig.top, labelconfig.width, labelconfig.height);
+ label->SetStyle(STYLE_TEXT_FONT, labelconfig.fontSize);
+ label->SetStyle(STYLE_LINE_HEIGHT, labelconfig.lineHeigh);
+ //TOOD: 待优化
+ if(labelconfig.textId == STR_DEEPSEEK) {
+ label->SetText("DeepSeek");
+ } else
+ label->SetTextId(labelconfig.textId);
+ label->SetLineBreakMode(labelconfig.lineBreakMode);
+ label->SetRollSpeed(23);
+ label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize);
+ return label;
+ }
+
+ UIButton *AivoiceMobileDataFailedStartView::AivoiceMobileDataFailedStartButtonInit(ButtonConfig &buttonconfig)
+ {
+ UIButton *button = new UIButton();
+ if (button == nullptr)
+ {
+ return nullptr;
+ }
+ button->SetPosition(buttonconfig.x, buttonconfig.y, buttonconfig.w, buttonconfig.h);
+ button->SetViewId(buttonconfig.ViewId);
+ button->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919);
+ button->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+ button->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff383838, UIButton::PRESSED);
+
+ return button;
+ }
+
+ UIImageView *AivoiceMobileDataFailedStartView::AivoiceMobileDataFailedStartImageInit(ImageConfig &imageconfig)
+ {
+ UIImageView *Image = new UIImageView();
+ if (Image == nullptr)
+ {
+ return nullptr;
+ }
+ Image->SetPosition(imageconfig.x, imageconfig.y, imageconfig.w, imageconfig.h);
+ return Image;
+ }
+
+ bool AivoiceMobileDataFailedStartView::CreateAivoiceMobileDataFailedStartScrollView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceMobileDataFailedStartView::CreateAivoiceMobileDataFailedStartScrollView");
+ scrollView = new UIScrollView();
+ if (scrollView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceMobileDataFailedStartView::scrollView new fail!");
+ return false;
+ }
+ scrollView->SetPosition(0, 0, 466, 466);
+ scrollView->SetTouchable(true);
+ scrollView->SetDraggable(true);
+ UIView::OnDragListener *dragListener = static_cast<UIView::OnDragListener *>(AiVoicePresenter::GetInstance());
+ if (dragListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceMobileDataFailedStartView::dragListener new fail!");
+ return false;
+ }
+ scrollView->SetOnDragListener(dragListener);
+
+ return true;
+ }
+
+ bool AivoiceMobileDataFailedStartView::CreateAivoiceMobileDataFailedStartLabel(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceMobileDataFailedStartView::CreateAivoiceMobileDataFailedStartLabel");
+ LabelConfig labelconfig = {
+ .left = 83,
+ .top = 50,
+ .width = 300,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = AiVoiceModel::GetInstance().GetAiModelTextId(),
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ title = AivoiceMobileDataFailedStartLabelInit(labelconfig);
+ if (title == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceMobileDataFailedStartView::title is nullptr!");
+ return false;
+ }
+ /* -------------------------------------------------------------------------- */
+ labelconfig.left = 53;
+ labelconfig.width = 360;
+ int textId[] = {STR_CONNECTION_FAIL, STR_PTALORTM}; /*连接失败,请稍后再重试或更换模型*/
+ for (int i = 0; i < sizeof(textId) / sizeof(textId[0]); i++)
+ {
+ labelconfig.top = 222 + i * 35;
+ labelconfig.textId = textId[i];
+ label[i] = AivoiceMobileDataFailedStartLabelInit(labelconfig);
+ if (label[i] == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceMobileDataFailedStartView::label[%d] is nullptr!", i);
+ return false;
+ }
+ }
+ /* -------------------------------------------------------------------------- */
+ labelconfig = {
+ .left = 133,
+ .top = 368,
+ .width = 200,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = STR_OK,
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ ensure = AivoiceMobileDataFailedStartLabelInit(labelconfig);
+ if (ensure == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceMobileDataFailedStartView::ensure is nullptr!");
+ return false;
+ }
+
+ return true;
+ }
+
+ bool AivoiceMobileDataFailedStartView::CreateAivoiceMobileDataFailedStartButton(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceMobileDataFailedStartView::CreateAivoiceMobileDataFailedStartButton");
+ ButtonConfig buttonconfig = {
+ .x = 93,
+ .y = 340,
+ .w = 280,
+ .h = 90,
+ .ViewId = AIMODEL_CONNECT_FAILED_ENSURE_BUTTON_VIEW_ID,
+ };
+ ensureButton = AivoiceMobileDataFailedStartButtonInit(buttonconfig);
+ if (ensureButton == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ensureButton new fail!");
+ return false;
+ }
+ UIView::OnTouchListener *touchListener = static_cast<UIView::OnTouchListener *>(AiVoicePresenter::GetInstance());
+ if (touchListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::touchListener can not be nullptr!");
+ return false;
+ }
+ ensureButton->SetOnTouchListener(touchListener);
+
+ return true;
+ }
+
+ bool AivoiceMobileDataFailedStartView::CreateAivoiceMobileDataFailedStartImage(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceMobileDataFailedStartView::CreateAivoiceMobileDataFailedStartImage");
+ ImageConfig imageconfig = {
+ .x = 193,
+ .y = 120,
+ .w = 80,
+ .h = 80,
+ };
+ attentionImage = AivoiceMobileDataFailedStartImageInit(imageconfig);
+ if (attentionImage == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "attentionImage new fail!");
+ return false;
+ }
+ attentionImage->SetStyle(STYLE_BORDER_RADIUS, 100);
+ attentionImage->SetSrc(PNG_ATTENTION_IMAGE);
+
+ return true;
+ }
+
+ UIScrollView *AivoiceMobileDataFailedStartView::CreateAivoiceMobileDataFailedStartView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceMobileDataFailedStartView::CreateAivoiceMobileDataFailedStartView");
+ if (scrollView == nullptr)
+ {
+ if (!CreateAivoiceMobileDataFailedStartScrollView() || !CreateAivoiceMobileDataFailedStartLabel() ||
+ !CreateAivoiceMobileDataFailedStartButton() || !CreateAivoiceMobileDataFailedStartImage())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceMobileDataFailedStartView::CreateAivoiceMobileDataFailedStartView fail!!");
+ return nullptr;
+ }
+ scrollView->Add(title);
+ scrollView->Add(attentionImage);
+ scrollView->Add(label[0]);
+ scrollView->Add(label[1]);
+ scrollView->Add(ensureButton);
+ scrollView->Add(ensure);
+ }
+ return scrollView;
+ }
+
+ void AivoiceMobileDataFailedStartView::UpdateTitleTextId(int textId)
+ {
+ if (title)
+ {
+ if(textId == STR_DEEPSEEK)
+ {
+ title->SetText("DeepSeek");
+ }
+ else
+ {
+ title->SetTextId(textId);
+ title->ForceResetText();
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-05-07 11:25:58
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2025-03-07 09:54:21
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/AiVoice/src/AivoiceReturnResultTextView.cpp
+ */
+#include "aivoice/include/AiVoicePresenter.h"
+#include "aivoice/include/AivoiceReturnResultTextView.h"
+#include "wearable_log.h"
+#include "ui_resource_string.h"
+#include "aivoice/include/AiVoiceModel.h"
+#include <UiConfig.h>
+#include <iostream>
+#include "string"
+
+namespace OHOS
+{
+
+ /* -------------------------------------------------------------------------- */
+ static constexpr const int16_t CHATCONTENT_LIST_X = 53;
+ static constexpr const int16_t CHATCONTENT_LIST_Y = 100;
+ static constexpr const int16_t CHATCONTENT_LIST_W = 360;
+ static constexpr const int16_t CHATCONTENT_LIST_H = 200;
+ static constexpr const int16_t REBOUNDSIZE = 30;
+ static constexpr const int16_t CHATCONTENT_SCROLLBLANKSIZE = 35;
+ static constexpr const int16_t MAX_SCR_DIS = 1000;
+ static constexpr const int16_t SNUM_2 = 2;
+
+ /* -------------------------------------------------------------------------- */
+ static constexpr const int16_t RETURN_BUTTON_X = 73;
+ static constexpr const int16_t RETURN_BUTTON_Y = CHATCONTENT_LIST_Y + CHATCONTENT_LIST_H + 10;
+ static constexpr const int16_t RETURN_BUTTON_W = 100;
+ static constexpr const int16_t RETURN_BUTTON_H = 100;
+ static constexpr const char *RETURN_BUTTON_PATH = "/user/res/AIVoice/AI_Union.bin";
+
+ static constexpr const int16_t CONTINUECHAT_BUTTON_X = 183;
+ static constexpr const int16_t CONTINUECHAT_BUTTON_Y = CHATCONTENT_LIST_Y + CHATCONTENT_LIST_H + 20;
+ static constexpr const int16_t CONTINUECHAT_BUTTON_W = 210;
+ static constexpr const int16_t CONTINUECHAT_BUTTON_H = 100;
+ /* -------------------------------------------------------------------------- */
+ static constexpr const int16_t CONTINUECHAT_X = CONTINUECHAT_BUTTON_X + 45;
+ static constexpr const int16_t CONTINUECHAT_Y = CONTINUECHAT_BUTTON_Y + 33;
+ static constexpr const int16_t CONTINUECHAT_W = 120;
+ static constexpr const int16_t CONTINUECHAT_H = 35;
+
+ static constexpr const int16_t ONE_HALF_NUM = 2;
+
+ static constexpr const int16_t LABEL_ROLL_SPEED = 70;
+
+ static AivoiceReturnResultTextView *g_pAivoiceReturnResultTextView{nullptr};
+
+ AivoiceReturnResultTextView::AivoiceReturnResultTextView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::AivoiceReturnResultTextView");
+ g_pAivoiceReturnResultTextView = this;
+ }
+
+ AivoiceReturnResultTextView::~AivoiceReturnResultTextView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::~AivoiceReturnResultTextView");
+ ClearAll();
+ g_pAivoiceReturnResultTextView = nullptr;
+ }
+
+ AivoiceReturnResultTextView *AivoiceReturnResultTextView::GetInstance()
+ {
+ return g_pAivoiceReturnResultTextView;
+ }
+
+ void AivoiceReturnResultTextView::ClearAll(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::ClearAll");
+ if (scrollView != nullptr)
+ {
+ scrollView->RemoveAll();
+
+ if (title != nullptr)
+ {
+ delete title;
+ title = nullptr;
+ }
+
+ if (chatContentListAdapter != nullptr)
+ {
+ delete chatContentListAdapter;
+ chatContentListAdapter = nullptr;
+ }
+
+ if (chatContentList != nullptr)
+ {
+ delete chatContentList;
+ chatContentList = nullptr;
+ }
+
+ if (returnButton != nullptr)
+ {
+ delete returnButton;
+ returnButton = nullptr;
+ }
+
+ if (continueChatButton != nullptr)
+ {
+ delete continueChatButton;
+ continueChatButton = nullptr;
+ }
+
+ if (continueChat != nullptr)
+ {
+ delete continueChat;
+ continueChat = nullptr;
+ }
+
+ delete scrollView;
+ scrollView = nullptr;
+ }
+ }
+
+ UILabelExt *AivoiceReturnResultTextView::AivoiceReturnResultTextLabelInit(LabelConfig &labelconfig)
+ {
+ UILabelExt *label = new UILabelExt();
+ if (label == nullptr)
+ {
+ return nullptr;
+ }
+ label->SetPosition(labelconfig.left, labelconfig.top, labelconfig.width, labelconfig.height);
+ label->SetStyle(STYLE_TEXT_FONT, labelconfig.fontSize);
+ label->SetStyle(STYLE_LINE_HEIGHT, labelconfig.lineHeight);
+ //TOOD: 待优化
+ if(labelconfig.textId == STR_DEEPSEEK) {
+ label->SetText("DeepSeek");
+ } else
+ label->SetTextId(labelconfig.textId);
+ label->SetLineBreakMode(labelconfig.lineBreakMode);
+ label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize);
+ label->SetRollSpeed(LABEL_ROLL_SPEED);
+ return label;
+ }
+
+ UIButton *AivoiceReturnResultTextView::AivoiceReturnResultTextButtonInit(ButtonConfig &buttonconfig)
+ {
+ UIButton *button = new UIButton();
+ if (button == nullptr)
+ {
+ return nullptr;
+ }
+ button->SetPosition(buttonconfig.x, buttonconfig.y, buttonconfig.w, buttonconfig.h);
+ button->SetViewId(buttonconfig.ViewId);
+ button->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919);
+ button->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+ button->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff383838, UIButton::PRESSED);
+
+ return button;
+ }
+
+ UIImageView *AivoiceReturnResultTextView::AivoiceReturnResultTextImageInit(ImageConfig &imageconfig)
+ {
+ UIImageView *Image = new UIImageView();
+ if (Image == nullptr)
+ {
+ return nullptr;
+ }
+ Image->SetPosition(imageconfig.x, imageconfig.y, imageconfig.w, imageconfig.h);
+ Image->SetSrc(imageconfig.src);
+ return Image;
+ }
+
+ bool AivoiceReturnResultTextView::CreateAivoiceReturnResultTextScrollView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::CreateAivoiceReturnResultTextScrollView");
+ scrollView = new UIScrollView();
+ if (scrollView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::scrollView new fail!");
+ return false;
+ }
+ scrollView->SetPosition(0, 0, 466, 466);
+ scrollView->SetTouchable(true);
+ scrollView->SetDraggable(true);
+ scrollView->SetDirection(UIScrollView::VERTICAL);
+
+ return true;
+ }
+
+ bool AivoiceReturnResultTextView::CreateAivoiceReturnResultTextLabel(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::CreateAivoiceReturnResultTextLabel");
+ LabelConfig labelconfig = {
+ .left = 83,
+ .top = 50,
+ .width = 300,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeight = 35,
+ .textId = AiVoiceModel::GetInstance().GetAiModelTextId(),
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ title = AivoiceReturnResultTextLabelInit(labelconfig);
+ if (title == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::title is nullptr!");
+ return false;
+ }
+ /* -------------------------------------------------------------------------- */
+ labelconfig = {
+ .left = CONTINUECHAT_X,
+ .top = CONTINUECHAT_Y,
+ .width = CONTINUECHAT_W,
+ .height = CONTINUECHAT_H,
+ .fontSize = 30,
+ .lineHeight = 35,
+ .textId = STR_CONTINUE_CHAT,
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ continueChat = AivoiceReturnResultTextLabelInit(labelconfig);
+ if (continueChat == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::continueChat is nullptr!");
+ return false;
+ }
+
+ return true;
+ }
+
+ bool AivoiceReturnResultTextView::CreateAivoiceReturnResultTextList(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::CreateAivoiceReturnResultTextList");
+ chatContentListAdapter = new AivoiceChatContentListAdapter();
+ if (chatContentListAdapter == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::chatContentListAdapter is nullptr");
+ return false;
+ }
+ UIView::OnClickListener *clickListener = static_cast<UIView::OnClickListener *>(AiVoicePresenter::GetInstance());
+ if (clickListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::chatContentListAdapter is nullptr");
+ return false;
+ }
+ chatContentListAdapter->SetItemClickListener(clickListener);
+
+ chatContentList = new UIList(UIList::VERTICAL);
+ if (chatContentList == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SettingView::OnStart::chatContentList is nullptr");
+ return false;
+ }
+ chatContentList->SetPosition(CHATCONTENT_LIST_X, CHATCONTENT_LIST_Y, CHATCONTENT_LIST_W, CHATCONTENT_LIST_H);
+ chatContentList->SetStyle(STYLE_BACKGROUND_COLOR, 0xff000000);
+ chatContentList->EnableAutoAlign(true);
+ chatContentList->SetTouchable(true);
+ chatContentList->SetDraggable(true);
+ chatContentList->SetThrowDrag(true);
+ // chatContentList->SetReboundSize(REBOUNDSIZE);
+ chatContentList->SetMaxScrollDistance(MAX_SCR_DIS);
+ chatContentList->SetSwipeACCLevel(200); // 800: compensation distance
+ chatContentList->SetDragACCLevel(5); // 5: drag acceleration
+ chatContentList->SetRotateFactor(2);
+ chatContentList->RequestFocus();
+ // chatContentList->SetIntercept(true);
+ chatContentList->SetAdapter(chatContentListAdapter);
+ chatContentList->RefreshList();
+ /* -------------------------------------------------------------------------- */
+ // AiVoiceModel::GetInstance().InitchatContentItems();
+ /* -------------------------------------------------------------------------- */
+ return true;
+ }
+
+ bool AivoiceReturnResultTextView::CreateAivoiceReturnResultTextButton(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::CreateAivoiceReturnResultTextButton");
+ ButtonConfig buttonconfig = {
+ .x = RETURN_BUTTON_X,
+ .y = RETURN_BUTTON_Y,
+ .w = RETURN_BUTTON_W,
+ .h = RETURN_BUTTON_H,
+ .ViewId = AIVOICERETURNRESULTTEXT_RETURN_BUTTON_VIEW_ID,
+ };
+ returnButton = AivoiceReturnResultTextButtonInit(buttonconfig);
+ if (returnButton == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "returnButton new fail!");
+ return false;
+ }
+ returnButton->SetImagePosition(39, 39);
+ returnButton->SetImageSrc(RETURN_BUTTON_PATH, RETURN_BUTTON_PATH);
+ UIView::OnTouchListener *touchListener = static_cast<UIView::OnTouchListener *>(AiVoicePresenter::GetInstance());
+ if (touchListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::touchListener can not be nullptr!");
+ return false;
+ }
+ returnButton->SetOnTouchListener(touchListener);
+ /* -------------------------------------------------------------------------- */
+ buttonconfig = {
+ .x = CONTINUECHAT_BUTTON_X,
+ .y = CONTINUECHAT_BUTTON_Y,
+ .w = CONTINUECHAT_BUTTON_W,
+ .h = CONTINUECHAT_BUTTON_H,
+ .ViewId = AIVOICERETURNRESULTTEXT_CONTINUECHAT_BUTTON_VIEW_ID,
+ };
+ continueChatButton = AivoiceReturnResultTextButtonInit(buttonconfig);
+ if (continueChatButton == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "continueChatButton new fail!");
+ return false;
+ }
+ continueChatButton->SetOnTouchListener(touchListener);
+
+ return true;
+ }
+
+ UIScrollView *AivoiceReturnResultTextView::CreateAivoiceReturnResultTextView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::CreateAivoiceReturnResultTextView");
+ if (scrollView == nullptr)
+ {
+ if (!CreateAivoiceReturnResultTextScrollView() || !CreateAivoiceReturnResultTextLabel() ||
+ !CreateAivoiceReturnResultTextList() || !CreateAivoiceReturnResultTextButton())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::CreateAivoiceReturnResultTextView fail!!");
+ return nullptr;
+ }
+ /* ----------------------------------- Add ---------------------------------- */
+ scrollView->Add(title);
+ scrollView->Add(chatContentList);
+ scrollView->Add(returnButton);
+ scrollView->Add(continueChatButton);
+ scrollView->Add(continueChat);
+ }
+ return scrollView;
+ }
+
+ /*添加对话内容到List*/
+ void AivoiceReturnResultTextView::AddChatContentToList(const ChatContentItem &item)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::AddChatContentToList");
+ chatContentListAdapter->AddListItem(item);
+ }
+
+ AivoiceChatContentListAdapter *AivoiceReturnResultTextView::GetAivoiceChatContentListAdapter(void)
+ {
+ return chatContentListAdapter;
+ }
+
+ UIList *AivoiceReturnResultTextView::GetChatContentList(void)
+ {
+ return chatContentList;
+ }
+
+ void AivoiceReturnResultTextView::UpdateTitleTextId(int textId)
+ {
+ if (title)
+ {
+ if(textId == STR_DEEPSEEK)
+ {
+ title->SetText("DeepSeek");
+ }
+ else
+ {
+ title->SetTextId(textId);
+ title->ForceResetText();
+ }
+ }
+ }
+
+ void AivoiceReturnResultTextView::IsScrollChatContentList(bool isScroll)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::IsScrollChatContentList");
+ if (isScroll)
+ {
+ scrollView->RequestFocus();
+ chatContentList->SetTouchable(false);
+ chatContentList->SetDraggable(false);
+ }
+ else
+ {
+ chatContentList->RequestFocus();
+ chatContentList->SetTouchable(true);
+ chatContentList->SetDraggable(true);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-05-07 11:25:58
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-11-05 11:18:14
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/AiVoice/src/AivoiceThinkingView.cpp
+ */
+#include "aivoice/include/AiVoicePresenter.h"
+#include "aivoice/include/AivoiceThinkingView.h"
+#include "wearable_log.h"
+#include "ui_resource_string.h"
+#include <UiConfig.h>
+#include "uicomponents/UIComponents.h"
+// #include "common/image_cache_manager.h"
+namespace OHOS
+{
+
+ static AivoiceThinkingView *g_pAivoiceThinkingView{nullptr};
+
+ AivoiceThinkingView::AivoiceThinkingView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::AivoiceThinkingView");
+ g_pAivoiceThinkingView = this;
+ }
+
+ AivoiceThinkingView::~AivoiceThinkingView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::~AivoiceThinkingView");
+ ClearAll();
+ g_pAivoiceThinkingView = nullptr;
+ }
+
+ AivoiceThinkingView *AivoiceThinkingView::GetInstance()
+ {
+ return g_pAivoiceThinkingView;
+ }
+
+ void AivoiceThinkingView::ClearAll(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::ClearAll");
+ if (scrollView != nullptr)
+ {
+ scrollView->RemoveAll();
+
+ if (title != nullptr)
+ {
+ delete title;
+ title = nullptr;
+ }
+
+ if (AiVoiceThinkingImageAnimatorView != nullptr)
+ {
+ AiVoiceThinkingImageAnimatorView->Stop();
+ delete AiVoiceThinkingImageAnimatorView;
+ AiVoiceThinkingImageAnimatorView = nullptr;
+
+ // FreeImagePathsArray(AiVoiceThinkingPathsArray, AIVOICE_THINKING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES);
+ FreeImageInfoArray(AiVoiceThinkingPathsArray, AIVoiceThinkingImagePaths, AIVOICE_THINKING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES);
+ }
+
+ if (cancelThink != nullptr)
+ {
+ delete cancelThink;
+ cancelThink = nullptr;
+ }
+
+ if (cancelThinkButton != nullptr)
+ {
+ delete cancelThinkButton;
+ cancelThinkButton = nullptr;
+ }
+
+ delete scrollView;
+ scrollView = nullptr;
+ }
+ }
+
+ UILabelExt *AivoiceThinkingView::AivoiceThinkingLabelInit(LabelConfig &labelconfig)
+ {
+ UILabelExt *label = new UILabelExt();
+ if (label == nullptr)
+ {
+ return nullptr;
+ }
+ label->SetPosition(labelconfig.left, labelconfig.top, labelconfig.width, labelconfig.height);
+ label->SetStyle(STYLE_TEXT_FONT, labelconfig.fontSize);
+ label->SetStyle(STYLE_LINE_HEIGHT, labelconfig.lineHeigh);
+ label->SetTextId(labelconfig.textId);
+ label->SetLineBreakMode(labelconfig.lineBreakMode);
+ label->SetRollSpeed(23);
+ label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize);
+ return label;
+ }
+
+ UIButton *AivoiceThinkingView::AivoiceThinkingButtonInit(ButtonConfig &buttonconfig)
+ {
+ UIButton *button = new UIButton();
+ if (button == nullptr)
+ {
+ return nullptr;
+ }
+ button->SetPosition(buttonconfig.x, buttonconfig.y, buttonconfig.w, buttonconfig.h);
+ button->SetViewId(buttonconfig.ViewId);
+ button->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919);
+ button->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+ button->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff383838, UIButton::PRESSED);
+
+ return button;
+ }
+
+ UIImageAnimatorView *AivoiceThinkingView::AivoiceThinkingImageAnimatorInit(ImageAnimatorConfig &imageanimatorconfig)
+ {
+ UIImageAnimatorView *animatorView = new UIImageAnimatorView();
+ if (animatorView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceThinkingImageAnimatorView::AiVoiceThinkingImageAnimatorView new fail");
+ return nullptr;
+ }
+
+ for (uint8_t i = 0; i < imageanimatorconfig.numFrames; i++)
+ {
+ imageanimatorconfig.imageInfoArray[i].imageInfo = (imageanimatorconfig.pathsArray[i]);
+ // imageanimatorconfig.imageInfoArray[i].imagePath = (imageanimatorconfig.pathsArray[i]);
+ // imageanimatorconfig.imageInfoArray[i].imageType = IMG_SRC_FILE_PATH;
+ imageanimatorconfig.imageInfoArray[i].imageType = IMG_SRC_IMAGE_INFO;
+ imageanimatorconfig.imageInfoArray[i].pos.x = imageanimatorconfig.x;
+ imageanimatorconfig.imageInfoArray[i].pos.y = imageanimatorconfig.y;
+ imageanimatorconfig.imageInfoArray[i].width = imageanimatorconfig.width;
+ imageanimatorconfig.imageInfoArray[i].height = imageanimatorconfig.height;
+ }
+
+ animatorView->SetPosition(imageanimatorconfig.x, imageanimatorconfig.y, imageanimatorconfig.width, imageanimatorconfig.height);
+ animatorView->SetImageAnimatorSrc(imageanimatorconfig.imageInfoArray, imageanimatorconfig.numFrames, imageanimatorconfig.delay);
+ animatorView->SetRepeat(true);
+ animatorView->SetSizeFixed(true);
+ // animatorView->SetAutoEnable(false);
+ // animatorView->SetResizeMode(UIImageAnimatorView::FILL);
+ animatorView->Start();
+
+ return animatorView;
+ }
+
+ bool AivoiceThinkingView::CreateAivoiceThinkingScrollView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::CreateAivoiceThinkingScrollView");
+ scrollView = new UIScrollView();
+ if (scrollView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::scrollView new fail!");
+ return false;
+ }
+ scrollView->SetPosition(0, 0, 466, 466);
+ UIView::OnDragListener *dragListener = static_cast<UIView::OnDragListener *>(AiVoicePresenter::GetInstance());
+ if (dragListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::dragListener new fail!");
+ return false;
+ }
+ scrollView->SetOnDragListener(dragListener);
+ scrollView->SetTouchable(true);
+ scrollView->SetDraggable(true);
+
+ return true;
+ }
+
+ bool AivoiceThinkingView::CreateAivoiceThinkingLabel(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::CreateAivoiceThinkingLabel");
+ LabelConfig labelconfig = {
+ .left = 83,
+ .top = 50,
+ .width = 300,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = STR_THINKING,
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ title = AivoiceThinkingLabelInit(labelconfig);
+ if (title == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::title is nullptr!");
+ return false;
+ }
+ /* -------------------------------------------------------------------------- */
+ labelconfig = {
+ .left = 133,
+ .top = 368,
+ .width = 200,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = STR_CANCEL,
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ cancelThink = AivoiceThinkingLabelInit(labelconfig);
+ if (cancelThink == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::cancelThink is nullptr!");
+ return false;
+ }
+ cancelThink->SetTextColor(Color::GetColorFromRGBA(0xfd, 0x52, 0x03, 0xff));
+
+ return true;
+ }
+
+ bool AivoiceThinkingView::CreateAivoiceThinkingButton(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::CreateAivoiceThinkingButton");
+ ButtonConfig buttonconfig = {
+ .x = 93,
+ .y = 340,
+ .w = 280,
+ .h = 90,
+ .ViewId = CANCEL_THINKING_BUTTON_VIEW_ID,
+ };
+ cancelThinkButton = AivoiceThinkingButtonInit(buttonconfig);
+ if (cancelThinkButton == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "cancelThinkButton new fail!");
+ return false;
+ }
+ UIView::OnTouchListener *touchListener = static_cast<UIView::OnTouchListener *>(AiVoicePresenter::GetInstance());
+ if (touchListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::touchListener can not be nullptr!");
+ return false;
+ }
+ cancelThinkButton->SetOnTouchListener(touchListener);
+
+ return true;
+ }
+
+ bool AivoiceThinkingView::CreateAivoiceThinkingImageAnimator(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::CreateAivoiceThinkingImageAnimator");
+ AiVoiceThinkingPathsArray = CreateImageInfoArray(AIVoiceThinkingImagePaths, AIVOICE_THINKING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES);
+ if (AiVoiceThinkingPathsArray == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::AiVoiceThinkingPathsArray is nullptr!!");
+ return false;
+ }
+
+ ImageAnimatorConfig imageanimatorconfig = {
+ .x = AIVOICE_THINKING_IMAGE_ANIMATOR_VIEW_X,
+ .y = AIVOICE_THINKING_IMAGE_ANIMATOR_VIEW_Y,
+ .width = AIVOICE_THINKING_IMAGE_ANIMATOR_VIEW_W,
+ .height = AIVOICE_THINKING_IMAGE_ANIMATOR_VIEW_H,
+ .imageInfoArray = AiVoiceThinkingImageInfo,
+ .pathsArray = AiVoiceThinkingPathsArray,
+ .numFrames = AIVOICE_THINKING_IMAGE_ANIMATOR_VIEW_NUM_FRAMES,
+ .delay = AIVOICE_THINKING_IMAGE_ANIMATOR_DELAY,
+ };
+ AiVoiceThinkingImageAnimatorView = AivoiceThinkingImageAnimatorInit(imageanimatorconfig);
+ if (AiVoiceThinkingImageAnimatorView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceThinkingImageAnimatorView::AiVoiceThinkingImageAnimatorView new fail");
+ return false;
+ }
+
+ return true;
+ }
+
+ UIScrollView *AivoiceThinkingView::CreateAivoiceThinkingView(void)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::CreateAivoiceThinkingView");
+#if 0
+ if (scrollView == nullptr)
+ {
+ if (!CreateAivoiceThinkingScrollView() || !CreateAivoiceThinkingLabel() ||
+ !CreateAivoiceThinkingButton() || !CreateAivoiceThinkingImageAnimator())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::CreateAivoiceThinkingView fail!!");
+ return nullptr;
+ }
+
+ scrollView->Add(title);
+ scrollView->Add(AiVoiceThinkingImageAnimatorView);
+ scrollView->Add(cancelThinkButton);
+ scrollView->Add(cancelThink);
+ }
+#endif
+ if (!CreateAivoiceThinkingScrollView())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::CreateAivoiceThinkingScrollView fail!!");
+ }
+ if (!CreateAivoiceThinkingLabel())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::CreateAivoiceThinkingLabel fail!!");
+ }
+ if (!CreateAivoiceThinkingButton())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::CreateAivoiceThinkingButton fail!!");
+ }
+ if (!CreateAivoiceThinkingImageAnimator())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::CreateAivoiceThinkingImageAnimator fail!!");
+ }
+
+ if (scrollView != nullptr)
+ {
+ if (title != nullptr)
+ {
+ scrollView->Add(title);
+ }
+ if (AiVoiceThinkingImageAnimatorView != nullptr)
+ {
+ scrollView->Add(AiVoiceThinkingImageAnimatorView);
+ }
+ if (cancelThinkButton != nullptr)
+ {
+ scrollView->Add(cancelThinkButton);
+ }
+ if (cancelThink != nullptr)
+ {
+ scrollView->Add(cancelThink);
+ }
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::CreateAivoiceThinkingView success!!");
+ return scrollView;
+ }
+ else
+ {
+ return nullptr;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-07-29 16:03:58
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-07-30 16:22:42
+ * @FilePath: /xts_origin/FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/apikeys/ApiKeysDeleteView.cpp
+ */
+
+#include "aivoice/include/apikeys/ApiKeysDeleteView.h"
+#include "aivoice/include/apikeys/ApiKeysPresenter.h"
+#include "wearable_log.h"
+#include "ui_resource_string.h"
+#include "UiConfig.h"
+namespace OHOS
+{
+ ApiKeysDeleteView::ApiKeysDeleteView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApiKeysDeleteView::ApiKeysDeleteView");
+ }
+
+ ApiKeysDeleteView::~ApiKeysDeleteView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApiKeysDeleteView::~ApiKeysDeleteView");
+ ClearAll();
+ }
+
+ void ApiKeysDeleteView::ClearAll(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApiKeysDeleteView::ClearAll");
+
+ if (ApiKeysDeleteScrollView != nullptr)
+ {
+ ApiKeysDeleteScrollView->RemoveAll();
+ if (clickListener != nullptr)
+ {
+ delete clickListener;
+ clickListener = nullptr;
+ }
+ if (dragListener != nullptr)
+ {
+ delete dragListener;
+ dragListener = nullptr;
+ }
+ if (ApiKeysDeleteTitleLabel != nullptr)
+ {
+ delete ApiKeysDeleteTitleLabel;
+ ApiKeysDeleteTitleLabel = nullptr;
+ }
+
+ if (ApiKeysDeleteNoteLabel != nullptr)
+ {
+ delete ApiKeysDeleteNoteLabel;
+ ApiKeysDeleteNoteLabel = nullptr;
+ }
+ if (ApiKeysDeleteButton != nullptr)
+ {
+ delete ApiKeysDeleteButton;
+ ApiKeysDeleteButton = nullptr;
+ }
+ if (ApiKeysCancelDeleteButton != nullptr)
+ {
+ delete ApiKeysCancelDeleteButton;
+ ApiKeysCancelDeleteButton = nullptr;
+ }
+ delete ApiKeysDeleteScrollView;
+ ApiKeysDeleteScrollView = nullptr;
+ }
+ }
+
+ UILabelExt *ApiKeysDeleteView::ApiKeysDeleteViewLabelInit(LabelConfig &labelconfig)
+ {
+ UILabelExt *label = new UILabelExt();
+ if (label == nullptr)
+ {
+ return nullptr;
+ }
+ label->SetPosition(labelconfig.left, labelconfig.top, labelconfig.width, labelconfig.height);
+ label->SetStyle(STYLE_TEXT_FONT, labelconfig.fontSize);
+ label->SetStyle(STYLE_LINE_HEIGHT, labelconfig.lineHeigh);
+ label->SetTextId(labelconfig.textId);
+ label->SetLineBreakMode(labelconfig.lineBreakMode);
+ label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ label->SetRollSpeed(23);
+ label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize);
+ return label;
+ }
+
+ bool ApiKeysDeleteView::CreateApiKeysDeleteViewLabel(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::CreateAiVoiceViewLabel");
+ LabelConfig labelConfig = {
+ .left = 83,
+ .top = 50,
+ .width = 300,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = STR_API_KEYS, /*API Keys*/
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ ApiKeysDeleteTitleLabel = ApiKeysDeleteViewLabelInit(labelConfig);
+ if (ApiKeysDeleteTitleLabel == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ApiKeysDeleteView::ApiKeysDeleteTitleLabel new fail!");
+ return false;
+ }
+ ApiKeysDeleteScrollView->Add(ApiKeysDeleteTitleLabel);
+ /* -------------------------------------------------------------------------- */
+ labelConfig.textId = STR_DYWTDAK;
+ labelConfig.top = 187;
+ ApiKeysDeleteNoteLabel = ApiKeysDeleteViewLabelInit(labelConfig);
+ if (ApiKeysDeleteNoteLabel == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ApiKeysDeleteView::ApiKeysDeleteNoteLabel new fail!");
+ return false;
+ }
+ ApiKeysDeleteNoteLabel->SetTextColor(Color::GetColorFromRGBA(0x99, 0x99, 0x99, 0xff));
+
+ ApiKeysDeleteScrollView->Add(ApiKeysDeleteNoteLabel);
+
+ return true;
+ }
+
+ /*删除API Keys视图*/
+ UIScrollView *ApiKeysDeleteView::CreateApiKeysDeleteView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApiKeysDeleteView::CreateApiKeysDeleteView");
+ if (ApiKeysDeleteScrollView == nullptr)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApiKeysDeleteView::CreateAiVoiceScrollView");
+ ApiKeysDeleteScrollView = new UIScrollView();
+ if (ApiKeysDeleteScrollView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ApiKeysDeleteView::CreateApiKeysDeleteScrollView new fail!");
+ return nullptr;
+ }
+ ApiKeysDeleteScrollView->SetPosition(0, 0, 466, 466);
+ ApiKeysDeleteScrollView->SetViewId(APIKEYS_DELETE_SCROLLVIEW_VIEWID);
+ ApiKeysDeleteScrollView->SetTouchable(true);
+ ApiKeysDeleteScrollView->SetDraggable(true);
+ if (dragListener == nullptr)
+ {
+ dragListener = new ApiKeysPresenter();
+ if (dragListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ApiKeysDeleteView::dragListener new fail!");
+ }
+ }
+ ApiKeysDeleteScrollView->SetOnDragListener(dragListener);
+ /* -------------------------------------------------------------------------- */
+ ApiKeysCancelDeleteButton = new UIButton();
+ if (ApiKeysCancelDeleteButton == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ApiKeysDeleteView::ApiKeysCancelDeleteButton new fail!");
+ return nullptr;
+ }
+ ApiKeysCancelDeleteButton->SetPosition(111, 299, 100, 100);
+ ApiKeysCancelDeleteButton->SetViewId(APIKEYS_CANCEL_DELETE_BUTTON_VIEWID);
+ ApiKeysCancelDeleteButton->SetImageSrc(PNG_SYSTEM_CHECK_OFF_IMAGE,PNG_SYSTEM_CHECK_OFF_IMAGE);
+ ApiKeysCancelDeleteButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xff000000);
+ ApiKeysCancelDeleteButton->SetStyle(STYLE_BACKGROUND_OPA, 0x00);
+ ApiKeysCancelDeleteButton->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff383838, UIButton::PRESSED);
+ ApiKeysDeleteScrollView->Add(ApiKeysCancelDeleteButton);
+ /* -------------------------------------------------------------------------- */
+ ApiKeysDeleteButton = new UIButton();
+ if (ApiKeysDeleteButton == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ApiKeysDeleteView::ApiKeysDeleteButton new fail!");
+ return nullptr;
+ }
+ ApiKeysDeleteButton->SetPosition(256, 299, 100, 100);
+ ApiKeysDeleteButton->SetViewId(APIKEYS_DELETE_BUTTON_VIEWID);
+ ApiKeysDeleteButton->SetImageSrc(PNG_SYSTEM_CHECK_ON_IMAGE,PNG_SYSTEM_CHECK_ON_IMAGE);
+ ApiKeysDeleteButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xff000000);
+ ApiKeysDeleteButton->SetStyle(STYLE_BACKGROUND_OPA, 0x00);
+ ApiKeysDeleteButton->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff383838, UIButton::PRESSED);
+ ApiKeysDeleteScrollView->Add(ApiKeysDeleteButton);
+ /* -------------------------------------------------------------------------- */
+ if (clickListener == nullptr)
+ {
+ clickListener = new ApiKeysPresenter();
+ if (clickListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ApiKeysDeleteView::clickListener new fail!");
+ }
+ }
+ ApiKeysCancelDeleteButton->SetOnClickListener(clickListener);
+ ApiKeysDeleteButton->SetOnClickListener(clickListener);
+ /* -------------------------------------------------------------------------- */
+ if (!CreateApiKeysDeleteViewLabel())
+ {
+ return nullptr;
+ }
+ }
+ return ApiKeysDeleteScrollView;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-07-29 16:14:16
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-09-07 12:19:09
+ * @FilePath: /xts_origin/FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/apikeys/ApiKeysPresenter.cpp
+ */
+
+#include "aivoice/include/apikeys/ApiKeysPresenter.h"
+#include "aivoice/include/apikeys/SetApiKeysView.h"
+#include "aivoice/include/apikeys/NotSetApiKeysView.h"
+#include "aivoice/include/AiVoiceView.h"
+#include "aivoice/include/AiVoiceModel.h"
+#include "wearable_log.h"
+#include "UiConfig.h"
+#include "iostream"
+#include "string"
+#include "map"
+namespace OHOS
+{
+
+ static ApiKeysPresenter *g_pApiKeysPresenter = nullptr;
+ ApiKeysPresenter::ApiKeysPresenter()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApiKeysPresenter::ApiKeysPresenter");
+ g_pApiKeysPresenter = this;
+ }
+
+ ApiKeysPresenter::~ApiKeysPresenter()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApiKeysPresenter::ApiKeysPresenter");
+ g_pApiKeysPresenter = nullptr;
+ }
+
+ ApiKeysPresenter *ApiKeysPresenter::GetInstance()
+ {
+ return g_pApiKeysPresenter;
+ }
+
+ bool ApiKeysPresenter::OnClick(UIView &view, const ClickEvent &event)
+ {
+ UNUSED(event);
+ std::string viewId = view.GetViewId();
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApiKeysPresenter::OnClick ,viewId = %s", viewId.c_str());
+
+ AiVoiceModel::GetInstance().reset_ai_screen60s_timer_time(); // 重置60s取消常亮屏timer
+
+ AiVoiceView *p_AiVoiceView = AiVoiceView::GetInstance();
+
+ std::map<std::string, std::pair<int, int>> viewMap = {
+ {SETAPIKEYS_DELETE_BUTTON_VIEWID, {AIVOICE_SETAPIKEYS, AIVOICE_APIKEYS_DELETE}}, /*进入到删除apikeys界面*/
+ {NOTSETAPIKEYS_ENSURE_BUTTON_VIEWID, {AIVOICE_NOTSETAPIKEYS, AIVOICE_STARTCHAT_VIEWID}}, /*退到AI对话界面*/
+ {APIKEYS_DELETE_BUTTON_VIEWID, {AIVOICE_APIKEYS_DELETE, AIVOICE_STARTCHAT_VIEWID}}, /*删除完apikeys退到AI对话界面*/
+ {APIKEYS_CANCEL_DELETE_BUTTON_VIEWID, {AIVOICE_APIKEYS_DELETE, AIVOICE_SETAPIKEYS}}, /*退到已设置apikeys界面*/
+ };
+
+ auto it = viewMap.find(viewId);
+ if (it != viewMap.end() && p_AiVoiceView != nullptr)
+ {
+ if (it->first == APIKEYS_DELETE_BUTTON_VIEWID)
+ {
+ AiVoiceModel::GetInstance().DeleteLocalOpenAIAPIKeys(); /*删除本地APIKeys*/
+ }
+ p_AiVoiceView->ChangeView(it->second.first, it->second.second);
+ }
+ return true;
+ }
+
+ bool ApiKeysPresenter::OnDrag(UIView &view, const DragEvent &event)
+ {
+ UNUSED(view);
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApiKeysPresenter::OnDrag");
+ if ((event.GetDeltaX() > X_DRAG_OFFSET) && (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) // 拖动过程中判断是否是水平滑动
+ {
+ ApiKeysPresenter::X_DRAG_FLAG = true;
+ }
+ return true;
+ }
+
+ bool ApiKeysPresenter::OnDragEnd(UIView &view, const DragEvent &event)
+ {
+ UNUSED(view);
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApiKeysPresenter::OnDragEnd");
+ std::string viewId = view.GetViewId();
+ AiVoiceView *p_AiVoiceView = AiVoiceView::GetInstance();
+ if (p_AiVoiceView == nullptr)
+ {
+ return false;
+ }
+ if (event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT && X_DRAG_FLAG)
+ {
+ std::map<std::string, std::pair<int, int>> viewMap = {
+ // {SETAPIKEYS_SCROLLVIEW_VIEWID, {AIVOICE_SETAPIKEYS, AIVOICE_STARTCHAT_VIEWID}},
+ // {NOTSETAPIKEYS_SCROLLVIEW_VIEWID, {AIVOICE_NOTSETAPIKEYS, AIVOICE_STARTCHAT_VIEWID}},
+ {APIKEYS_DELETE_SCROLLVIEW_VIEWID, {AIVOICE_APIKEYS_DELETE, AIVOICE_SETAPIKEYS}},
+ };
+
+ auto it = viewMap.find(viewId);
+ if (it != viewMap.end())
+ {
+ p_AiVoiceView->ChangeView(it->second.first, it->second.second);
+ }
+ X_DRAG_FLAG = false;
+ }
+ else if (event.GetDragDirection() == DragEvent::DIRECTION_TOP_TO_BOTTOM) /*下滑*/
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "DIRECTION_TOP_TO_BOTTOM");
+ if (viewId == SETAPIKEYS_SCROLLVIEW_VIEWID)
+ {
+ p_AiVoiceView->ChangeView(AIVOICE_SETAPIKEYS, AIVOICE_STARTCHAT_VIEWID); /*API Keys set界面->开始对话界面*/
+ }
+ else if (viewId == NOTSETAPIKEYS_SCROLLVIEW_VIEWID)
+ {
+ p_AiVoiceView->ChangeView(AIVOICE_NOTSETAPIKEYS, AIVOICE_STARTCHAT_VIEWID); /*API Keys notset界面->开始对话界面*/
+ }
+ }
+ return true;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-07-29 16:04:23
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-11-05 11:20:24
+ * @FilePath: /xts_origin/FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/apikeys/NotSetApiKeysView.cpp
+ */
+
+#include "aivoice/include/apikeys/NotSetApiKeysView.h"
+#include "aivoice/include/apikeys/ApiKeysPresenter.h"
+#include "wearable_log.h"
+#include "ui_resource_string.h"
+namespace OHOS
+{
+ NotSetApiKeysView::NotSetApiKeysView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "NotSetApiKeysView::NotSetApiKeysView");
+ }
+
+ NotSetApiKeysView::~NotSetApiKeysView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "NotSetApiKeysView::~NotSetApiKeysView");
+ ClearAll();
+ }
+
+ void NotSetApiKeysView::ClearAll(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "NotSetApiKeysView::ClearAll");
+
+ if (NotSetApiKeysScrollView != nullptr)
+ {
+ NotSetApiKeysScrollView->RemoveAll();
+ if (clickListener != nullptr)
+ {
+ delete clickListener;
+ clickListener = nullptr;
+ }
+ if (dragListener != nullptr)
+ {
+ delete dragListener;
+ dragListener = nullptr;
+ }
+ if (NotSetApiKeysTitleLabel != nullptr)
+ {
+ delete NotSetApiKeysTitleLabel;
+ NotSetApiKeysTitleLabel = nullptr;
+ }
+ for (int i = 0; i < static_cast<int>(sizeof(NotSetApiKeysNoteLabel) / sizeof(NotSetApiKeysNoteLabel[0])); i++)
+ {
+ if (NotSetApiKeysNoteLabel[i] != nullptr)
+ {
+ delete NotSetApiKeysNoteLabel[i];
+ NotSetApiKeysNoteLabel[i] = nullptr;
+ }
+ }
+ if (NotSetApiKeysEnsureLabel != nullptr)
+ {
+ delete NotSetApiKeysEnsureLabel;
+ NotSetApiKeysEnsureLabel = nullptr;
+ }
+ if (NotSetApiKeysEnsureButton != nullptr)
+ {
+ delete NotSetApiKeysEnsureButton;
+ NotSetApiKeysEnsureButton = nullptr;
+ }
+ delete NotSetApiKeysScrollView;
+ NotSetApiKeysScrollView = nullptr;
+ }
+ }
+
+ UILabelExt *NotSetApiKeysView::NotSetApiKeysViewLabelInit(LabelConfig &labelconfig)
+ {
+ UILabelExt *label = new UILabelExt();
+ if (label == nullptr)
+ {
+ return nullptr;
+ }
+ label->SetPosition(labelconfig.left, labelconfig.top, labelconfig.width, labelconfig.height);
+ label->SetStyle(STYLE_TEXT_FONT, labelconfig.fontSize);
+ label->SetStyle(STYLE_LINE_HEIGHT, labelconfig.lineHeigh);
+ label->SetTextId(labelconfig.textId);
+ label->SetLineBreakMode(labelconfig.lineBreakMode);
+ label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ label->SetRollSpeed(23);
+ label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize);
+ return label;
+ }
+
+ bool NotSetApiKeysView::CreateNotSetApiKeysViewLabel(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::CreateAiVoiceViewLabel");
+ LabelConfig labelConfig = {
+ .left = 83,
+ .top = 50,
+ .width = 300,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = STR_API_KEYS, /*API Keys*/
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ NotSetApiKeysTitleLabel = NotSetApiKeysViewLabelInit(labelConfig);
+ if (NotSetApiKeysTitleLabel == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "NotSetApiKeysView::NotSetApiKeysTitleLabel new fail!");
+ return false;
+ }
+ NotSetApiKeysScrollView->Add(NotSetApiKeysTitleLabel);
+ /* -------------------------------------------------------------------------- */
+ int textId[] = {STR_PGTTAF, STR_DAFBS, STR_OPENAI_API_KEYS};
+ for (int i = 0; i < static_cast<int>((sizeof(textId) / sizeof(textId[0]))); i++)
+ {
+ labelConfig.left = 53;
+ labelConfig.top = 161 + i * 35;
+ labelConfig.width = 360;
+ labelConfig.textId = textId[i];
+ NotSetApiKeysNoteLabel[i] = NotSetApiKeysViewLabelInit(labelConfig);
+ if (NotSetApiKeysNoteLabel[i] == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "NotSetApiKeysView::NotSetApiKeysNoteLabel[%d] new fail!", i);
+ return false;
+ }
+ NotSetApiKeysScrollView->Add(NotSetApiKeysNoteLabel[i]);
+ }
+ /* -------------------------------------------------------------------------- */
+ labelConfig.left = 133;
+ labelConfig.top = 368;
+ labelConfig.width = 200;
+ labelConfig.textId = STR_OK; /*确定*/
+ NotSetApiKeysEnsureLabel = NotSetApiKeysViewLabelInit(labelConfig);
+ if (NotSetApiKeysEnsureLabel == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "NotSetApiKeysView::NotSetApiKeysEnsureLabel new fail!");
+ return false;
+ }
+ NotSetApiKeysScrollView->Add(NotSetApiKeysEnsureLabel);
+ return true;
+ }
+
+ /*未配置了API Keys视图*/
+ UIScrollView *NotSetApiKeysView::CreateNotSetApiKeysView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "NotSetApiKeysView::CreateNotSetApiKeysView");
+ if (NotSetApiKeysScrollView == nullptr)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "NotSetApiKeysView::CreateAiVoiceScrollView");
+ NotSetApiKeysScrollView = new UIScrollView();
+ if (NotSetApiKeysScrollView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "NotSetApiKeysView::CreateNotSetApiKeysScrollView new fail!");
+ return nullptr;
+ }
+ NotSetApiKeysScrollView->SetPosition(0, 0, 466, 466);
+ NotSetApiKeysScrollView->SetViewId(NOTSETAPIKEYS_SCROLLVIEW_VIEWID);
+ NotSetApiKeysScrollView->SetTouchable(true);
+ NotSetApiKeysScrollView->SetDraggable(true);
+ if (dragListener == nullptr)
+ {
+ dragListener = new ApiKeysPresenter();
+ if (dragListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "NotSetApiKeysView::dragListener new fail!");
+ }
+ }
+ NotSetApiKeysScrollView->SetOnDragListener(dragListener);
+ /* -------------------------------------------------------------------------- */
+ NotSetApiKeysEnsureButton = new UIButton();
+ if (NotSetApiKeysEnsureButton == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "NotSetApiKeysView::NotSetApiKeysEnsureButton new fail!");
+ return nullptr;
+ }
+ NotSetApiKeysEnsureButton->SetPosition(93, 340, 280, 90);
+ NotSetApiKeysEnsureButton->SetViewId(NOTSETAPIKEYS_ENSURE_BUTTON_VIEWID);
+ NotSetApiKeysEnsureButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xfffd5213);
+ NotSetApiKeysEnsureButton->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff383838, UIButton::PRESSED);
+ if (clickListener == nullptr)
+ {
+ clickListener = new ApiKeysPresenter();
+ if (clickListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "NotSetApiKeysView::clickListener new fail!");
+ }
+ }
+ NotSetApiKeysEnsureButton->SetOnClickListener(clickListener);
+ NotSetApiKeysScrollView->Add(NotSetApiKeysEnsureButton);
+ /* -------------------------------------------------------------------------- */
+ if (!CreateNotSetApiKeysViewLabel())
+ {
+ return nullptr;
+ }
+ }
+ return NotSetApiKeysScrollView;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-07-29 16:04:23
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-11-05 11:20:35
+ * @FilePath: /xts_origin/FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/apikeys/SetApiKeysView.cpp
+ */
+
+#include "aivoice/include/apikeys/SetApiKeysView.h"
+#include "aivoice/include/apikeys/ApiKeysPresenter.h"
+#include "wearable_log.h"
+#include "ui_resource_string.h"
+namespace OHOS
+{
+ SetApiKeysView::SetApiKeysView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetApiKeysView::SetApiKeysView");
+ }
+
+ SetApiKeysView::~SetApiKeysView()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetApiKeysView::~SetApiKeysView");
+ ClearAll();
+ }
+
+ void SetApiKeysView::ClearAll(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetApiKeysView::ClearAll");
+
+ if (SetApiKeysScrollView != nullptr)
+ {
+ SetApiKeysScrollView->RemoveAll();
+ if (clickListener != nullptr)
+ {
+ delete clickListener;
+ clickListener = nullptr;
+ }
+ if (dragListener != nullptr)
+ {
+ delete dragListener;
+ dragListener = nullptr;
+ }
+ if (SetApiKeysTitleLabel != nullptr)
+ {
+ delete SetApiKeysTitleLabel;
+ SetApiKeysTitleLabel = nullptr;
+ }
+ if (SetApiKeysImage != nullptr)
+ {
+ delete SetApiKeysImage;
+ SetApiKeysImage = nullptr;
+ }
+ if (SetApiKeysDeleteLabel != nullptr)
+ {
+ delete SetApiKeysDeleteLabel;
+ SetApiKeysDeleteLabel = nullptr;
+ }
+ if (SetApiKeysNoteLabel[0] != nullptr)
+ {
+ delete SetApiKeysNoteLabel[0];
+ SetApiKeysNoteLabel[0] = nullptr;
+ }
+ if (SetApiKeysNoteLabel[1] != nullptr)
+ {
+ delete SetApiKeysNoteLabel[1];
+ SetApiKeysNoteLabel[1] = nullptr;
+ }
+ if (SetApiKeysDeleteButton != nullptr)
+ {
+ delete SetApiKeysDeleteButton;
+ SetApiKeysDeleteButton = nullptr;
+ }
+ delete SetApiKeysScrollView;
+ SetApiKeysScrollView = nullptr;
+ }
+ }
+
+ UILabelExt *SetApiKeysView::SetApiKeysViewLabelInit(LabelConfig &labelconfig)
+ {
+ UILabelExt *label = new UILabelExt();
+ if (label == nullptr)
+ {
+ return nullptr;
+ }
+ label->SetPosition(labelconfig.left, labelconfig.top, labelconfig.width, labelconfig.height);
+ label->SetStyle(STYLE_TEXT_FONT, labelconfig.fontSize);
+ label->SetStyle(STYLE_LINE_HEIGHT, labelconfig.lineHeigh);
+ label->SetTextId(labelconfig.textId);
+ label->SetLineBreakMode(labelconfig.lineBreakMode);
+ label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+ label->SetRollSpeed(23);
+ label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize);
+ return label;
+ }
+
+ bool SetApiKeysView::CreateSetApiKeysViewLabel(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetApiKeysView::CreateSetApiKeysViewLabel");
+ LabelConfig labelConfig = {
+ .left = 83,
+ .top = 50,
+ .width = 300,
+ .height = 35,
+ .fontSize = 30,
+ .lineHeigh = 35,
+ .textId = STR_API_KEYS, /*API Keys*/
+ .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION,
+ };
+ SetApiKeysTitleLabel = SetApiKeysViewLabelInit(labelConfig);
+ if (SetApiKeysTitleLabel == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetApiKeysView::SetApiKeysTitleLabel new fail!");
+ return false;
+ }
+ SetApiKeysScrollView->Add(SetApiKeysTitleLabel);
+ /* -------------------------------------------------------------------------- */
+ int textId[] = {STR_KHBB, STR_GTAS};
+ for (int i = 0; i < static_cast<int>((sizeof(textId) / sizeof(textId[0]))); i++)
+ {
+ labelConfig.left = 53;
+ labelConfig.top = 235 + i * 35;
+ labelConfig.width = 360;
+ labelConfig.textId = textId[i];
+ SetApiKeysNoteLabel[i] = SetApiKeysViewLabelInit(labelConfig);
+ if (SetApiKeysNoteLabel[i] == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetApiKeysView::SetApiKeysNoteLabel[%d] new fail!", i);
+ return false;
+ }
+ SetApiKeysScrollView->Add(SetApiKeysNoteLabel[i]);
+ }
+ /* -------------------------------------------------------------------------- */
+ labelConfig.left = 133;
+ labelConfig.top = 368;
+ labelConfig.width = 200;
+ labelConfig.textId = STR_DELETE; /*删除*/
+ SetApiKeysDeleteLabel = SetApiKeysViewLabelInit(labelConfig);
+ if (SetApiKeysDeleteLabel == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetApiKeysView::SetApiKeysDeleteLabel new fail!");
+ return false;
+ }
+ SetApiKeysScrollView->Add(SetApiKeysDeleteLabel);
+ return true;
+ }
+
+ /*成功配置了API Keys视图*/
+ UIScrollView *SetApiKeysView::CreateSetApiKeysView(void)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetApiKeysView::CreateSetApiKeysView");
+ if (SetApiKeysScrollView == nullptr)
+ {
+ SetApiKeysScrollView = new UIScrollView();
+ if (SetApiKeysScrollView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetApiKeysView::CreateSetApiKeysScrollView new fail!");
+ return nullptr;
+ }
+ SetApiKeysScrollView->SetPosition(0, 0, 466, 466);
+ SetApiKeysScrollView->SetViewId(SETAPIKEYS_SCROLLVIEW_VIEWID);
+ SetApiKeysScrollView->SetTouchable(true);
+ SetApiKeysScrollView->SetDraggable(true);
+ if (dragListener == nullptr)
+ {
+ dragListener = new ApiKeysPresenter();
+ if (dragListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetApiKeysView::dragListener new fail!");
+ }
+ }
+ SetApiKeysScrollView->SetOnDragListener(dragListener);
+ /* -------------------------------------------------------------------------- */
+ SetApiKeysImage = new UIImageView();
+ if (SetApiKeysImage == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetApiKeysView::SetApiKeysImage new fail!");
+ }
+ SetApiKeysImage->SetPosition(193, 121, 80, 80);
+ SetApiKeysImage->SetSrc(SETAPIKEYS_IMAGE_PATH);
+ SetApiKeysScrollView->Add(SetApiKeysImage);
+ /* -------------------------------------------------------------------------- */
+ SetApiKeysDeleteButton = new UIButton();
+ if (SetApiKeysDeleteButton == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetApiKeysView::SetApiKeysDeleteButton new fail!");
+ return nullptr;
+ }
+ SetApiKeysDeleteButton->SetPosition(93, 340, 280, 90);
+ SetApiKeysDeleteButton->SetViewId(SETAPIKEYS_DELETE_BUTTON_VIEWID);
+ SetApiKeysDeleteButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xfffd5213);
+ SetApiKeysDeleteButton->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff383838, UIButton::PRESSED);
+ if (clickListener == nullptr)
+ {
+ clickListener = new ApiKeysPresenter();
+ if (clickListener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetApiKeysView::clickListener new fail!");
+ }
+ }
+ SetApiKeysDeleteButton->SetOnClickListener(clickListener);
+ SetApiKeysScrollView->Add(SetApiKeysDeleteButton);
+ /* -------------------------------------------------------------------------- */
+ if (!CreateSetApiKeysViewLabel())
+ {
+ return nullptr;
+ }
+ }
+ return SetApiKeysScrollView;
+ }
+}
\ No newline at end of file