From 275fe6d461eb5d122eb201341dd6ca88ada8bc46 Mon Sep 17 00:00:00 2001 From: luozheng <1732036298@qq.com> Date: Thu, 27 Mar 2025 10:05:47 +0800 Subject: [PATCH] =?utf8?q?=E5=BD=95=E9=9F=B3slice=E5=90=88=E5=B9=B6?= =?utf8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../record/include/RecordDeleteView.h | 61 + .../nativeui/record/include/RecordGoingView.h | 62 + .../nativeui/record/include/RecordListView.h | 66 + .../record/include/RecordingListAdapter.h | 67 + .../record/include/RecordingListitemView.h | 33 + .../nativeui/record/include/RecordingModel.h | 165 +++ .../nativeui/record/include/RecordingModelC.h | 27 + .../record/include/RecordingNumLimitView.h | 50 + .../record/include/RecordingPlayerView.h | 100 ++ .../record/include/RecordingPresenter.h | 165 +++ .../nativeui/record/include/RecordingView.h | 103 ++ .../include/RecordingVolumeSettingView.h | 31 + .../nativeui/record/src/RecordDeleteView.cpp | 235 ++++ .../nativeui/record/src/RecordGoingView.cpp | 275 ++++ .../nativeui/record/src/RecordListView.cpp | 306 ++++ .../record/src/RecordingListAdapter.cpp | 93 ++ .../record/src/RecordingListitemView.cpp | 87 ++ .../nativeui/record/src/RecordingModel.cpp | 1225 +++++++++++++++++ .../record/src/RecordingNumLimitView.cpp | 213 +++ .../record/src/RecordingPlayerView.cpp | 476 +++++++ .../record/src/RecordingPresenter.cpp | 895 ++++++++++++ .../nativeui/record/src/RecordingView.cpp | 460 +++++++ .../record/src/RecordingVolumeSettingView.cpp | 74 + 23 files changed, 5269 insertions(+) create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordDeleteView.h create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordGoingView.h create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordListView.h create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingListAdapter.h create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingListitemView.h create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingModel.h create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingModelC.h create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingNumLimitView.h create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingPlayerView.h create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingPresenter.h create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingView.h create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingVolumeSettingView.h create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordDeleteView.cpp create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordGoingView.cpp create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordListView.cpp create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingListAdapter.cpp create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingListitemView.cpp create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingModel.cpp create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingNumLimitView.cpp create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingPlayerView.cpp create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingPresenter.cpp create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingView.cpp create mode 100644 code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingVolumeSettingView.cpp diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordDeleteView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordDeleteView.h new file mode 100644 index 000000000..a6666f5e6 --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordDeleteView.h @@ -0,0 +1,61 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-03-30 09:14:38 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-08-31 20:51:23 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/record/include/RecordDeleteView.h + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +#ifndef RECORD_DELETE_VIEW_H +#define RECORD_DELETE_VIEW_H + + +#include "View.h" + +#include "components/ui_scroll_view.h" +#include "components/ui_image_view.h" +#include "components/ui_button.h" +#include "components/ui_label_ext.h" +#include "ui_resource_string.h" +namespace OHOS +{ + + class RecordDeleteView + { + + public: + struct LabelConfig + { + int16_t left; + int16_t top; + int16_t width; + int16_t height; + int16_t fontSize; // 字体大小 + int16_t lineHeigh; // 行高 + const char *text; // 文本 + int16_t textId; // 文本Id + uint8_t lineBreakMode; // 断行模式。 + }; + RecordDeleteView(); + virtual ~RecordDeleteView(); + static RecordDeleteView *GetInstance(void); + UIScrollView *RecordDeleteViewInit(void); + void SetRecordDeleteName(const char * name); + + private: + UILabelExt *CreateRecordDeleteLabel(LabelConfig &labelconfig); // 设置标签 + bool RecordDeleteScrollViewInit(void); + bool RecordDeleteLabelViewInit(void); + bool RecordDeleteButtonViewInit(void); + void ClearAll(void); + + UIScrollView *RecordDeleteViewScrollView{nullptr}; + UILabelExt *TitleLabel{nullptr}; + UILabelExt *AttentionLabel{nullptr}; + UILabelExt *DeleteNameLabel{nullptr}; + UIButton *RECORD_DELETE_ON_BUTTON{nullptr}; // 是否删除录音:是 + UIButton *RECORD_DELETE_OFF_BUTTON{nullptr}; // 是否删除录音:否 + std::string mergefileName; + }; +} // namespace OHOS +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordGoingView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordGoingView.h new file mode 100644 index 000000000..376d70f47 --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordGoingView.h @@ -0,0 +1,62 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-03-30 09:14:38 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-10-28 18:56:01 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/record/include/RecordGoingView.h + */ +#ifndef RECORD_GOING_VIEW_H +#define RECORD_GOING_VIEW_H + + +#include "View.h" + +#include "components/ui_label.h" +#include "components/ui_label_ext.h" +#include "components/ui_image_view.h" +#include "components/ui_button.h" +#include "components/ui_scroll_view.h" +namespace OHOS +{ + + class RecordGoingView + { + public: + struct LabelConfig + { + int16_t left; + int16_t top; + int16_t width; + int16_t height; + int16_t fontSize; // 字体大小 + int16_t lineHeigh; // 行高 + const char *text; // 文本 + int16_t textId; // 文本Id + uint8_t lineBreakMode; // 断行模式。 + }; + RecordGoingView(); + virtual ~RecordGoingView(); + static RecordGoingView *GetInstance(void); + UIScrollView *RecordGoingViewInit(void); + void ClearAll(void); + UILabel *GetRecordingDurationLabel(void); + + private: + UILabel *CreateRecordGoingLabel(LabelConfig &labelconfig); // 设置标签 + UILabelExt *CreateRecordGoingLabelExt(LabelConfig &labelconfig); // 设置标签 + bool RecordGoingScrollViewInit(void); + bool RecordGoingLabelViewInit(void); + bool RecordGoingImageViewInit(void); + bool RecordGoingButtonViewInit(void); + void AddViewsToScrollView(UIScrollView *scrollView, UIView *views[], int numViews); + void AddViewsToRecordGoingViewScrollView(); + UIScrollView *RecordGoingViewScrollView{nullptr}; + UILabelExt *TitleLabel{nullptr}; // 标题 + UILabelExt *RecordGoingLabel{nullptr}; // “录音中” + UILabel *Timer{nullptr}; // 显示录音时长 + UIImageView *RECORD_GOING_IMAGE{nullptr}; + UIButton *RECORD_GOING_BUTTON{nullptr}; + UIButton *STOP_RECORD_GOING_BUTTON{nullptr}; + }; +} // namespace OHOS +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordListView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordListView.h new file mode 100644 index 000000000..b19ba7a17 --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordListView.h @@ -0,0 +1,66 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-03-30 09:14:38 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-08-26 16:10:38 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/record/include/RecordListView.h + */ +#ifndef RECORD_LIST_VIEW_H +#define RECORD_LIST_VIEW_H + + +#include "View.h" + +#include "components/ui_view_group.h" +#include "components/ui_scroll_view.h" +#include "components/ui_label.h" +#include "components/ui_label_ext.h" +#include "components/ui_image_view.h" +#include "components/ui_button.h" +#include "components/ui_list.h" +#include "record/include/RecordingListAdapter.h" +namespace OHOS +{ + static constexpr const char *RECORDLISTSCROLLVIEW = "RecordListScrollView"; + class RecordListView + { + + public: + struct LabelConfig + { + int16_t left; + int16_t top; + int16_t width; + int16_t height; + int16_t fontSize; // 字体大小 + int16_t lineHeigh; // 行高 + const char *text; // 文本 + int16_t textId; // 文本id + uint8_t lineBreakMode; // 断行模式。 + }; + RecordListView(); + virtual ~RecordListView(); + static RecordListView *GetInstance(void); + UIScrollView *RecordListViewInit(void); + void RefreshRecordingListData(void); + + private: + UILabelExt *CreateRecordListLabel(LabelConfig &labelconfig); // 设置标签 + bool RecordListScrollViewInit(void); + bool RecordListLabelViewInit(void); + bool RecordListListViewInit(void); + void AddRecordingToList(const RecordingListItem &item); + void InitRecordingInfo(void); + void ClearAll(void); + void IsVisibleLabel(bool value); + + UIScrollView *RecordListScrollView{nullptr}; + UILabelExt *RecordListViewTitleLabel{nullptr}; // "录音列表" + UILabelExt *RecordListViewAttentionLabel{nullptr}; //"当前录音列表为空" + UIList *recordList{nullptr}; // 录音列表 + RecordingListAdapter *p_RecordingListAdapter{nullptr}; // 录音列表适配器 + UIView::OnClickListener *clickListener{nullptr}; + }; +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingListAdapter.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingListAdapter.h new file mode 100644 index 000000000..59bac81d0 --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingListAdapter.h @@ -0,0 +1,67 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-08-05 15:20:03 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-08-31 20:19:31 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/record/include/RecordingListAdapter.h + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +#ifndef RECORDING_LIST_ADAPTER_H +#define RECORDING_LIST_ADAPTER_H + +#include "components/abstract_adapter.h" +#include "components/ui_list.h" +#include "list.h" +#include +namespace OHOS +{ + typedef struct + { + int index; + std::string recordId; // 录音名 + const char *recordTotalTime; // 录音总时长 + const char *recordTime; // 录音时间 + } RecordingListItem; + + class RecordingListAdapter : public AbstractAdapter + { + public: + explicit RecordingListAdapter(); + virtual ~RecordingListAdapter(); + + /* * + * @brief Sets the UIView adapter data, which is a RecordingListItem linked list. + * + * @param data Indicates the RecordingListItem linked list data. + * @since 1.0 + * @version 1.0 + */ + void SetData(std::list &data); + + void ClearData(void); + /* * + * @brief Obtains the data size of the UILabel adapter. + * + * @return Returns the data size of the UILabel adapter. + * @since 1.0 + * @version 1.0 + */ + virtual uint16_t GetCount(void) override; + + virtual UIView *GetView(UIView *inView, int16_t index) override; + + virtual void AddListItem(const RecordingListItem &item); + + void SetItemClickListener(UIView::OnClickListener *itemclicklistener) + { + itemClickListener = itemclicklistener; + } + + private: + std::list listData; + UIView::OnClickListener *itemClickListener{nullptr}; + }; + +} + +#endif diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingListitemView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingListitemView.h new file mode 100644 index 000000000..97d105da1 --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingListitemView.h @@ -0,0 +1,33 @@ +#ifndef RECORDING_LIST_ITEM_VIEW +#define RECORDING_LIST_ITEM_VIEW + +#include "components/ui_view_group.h" +#include "components/ui_button.h" +#include "components/ui_label.h" +#include "components/ui_label_ext.h" +#include "record/include/RecordingListAdapter.h" + +namespace OHOS +{ + class RecordingListitemView : public UIViewGroup + { + public: + RecordingListitemView(); + virtual ~RecordingListitemView(); + virtual void SetItemInfo(const RecordingListItem itemInfo); + virtual void SetUpChild(); + int GetRecordingListIndex(); + + private: + RecordingListitemView(const RecordingListitemView &); + void SetLabelStyle(UILabel &label, int x, int y, int width, int height, OHOS::ColorType textColor, int fontSize); + UIButton m_button; + UILabel m_recordId; // 录音编号 + UILabel m_recordTotalTime; // 录音总时长 + UILabel m_recordTime; // 录音时间 + RecordingListItem m_ItemInfo{0, nullptr,nullptr,nullptr}; + }; + +} + +#endif diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingModel.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingModel.h new file mode 100644 index 000000000..4aaa71ba3 --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingModel.h @@ -0,0 +1,165 @@ +#ifndef RECORDING_MODEL_H +#define RECORDING_MODEL_H + +#include "stdio.h" +#include "gfx_utils/list.h" +#include "UiServersMsg.h" +#include "audio_manager.h" +#include "audio_base_type.h" +#include "record/include/RecordingPresenter.h" +#include "record/include/RecordingListAdapter.h" + +#include +#include +#include +#include +#include +#include "../../../../../../middleware/services/media/foundation/utils/include/source.h" +#include "../../../../../../middleware/services/media/foundation/player/interfaces/kits/player.h" +namespace OHOS +{ + using OHOS::Media::Player; + using OHOS::Media::Source; + using namespace OHOS::Media; + using namespace ::Audio; + using Audio::AudioManager; + + /* + * @brief 录音播放器状态 + */ + enum RecorderPlayerStatus + { + RECORDER_NORMAL, + RECORDER_ALREADY_PLAYING, // 录音播放中 + RECORDER_ALREADY_PAUSED, // 录音暂停 + RECORDER_ALREADY_STOPPED, // 录音停止 + RECORDER_PLAYBACK_COMPLETED, // 录音播放完成 + RECORDER_EXECUTE_FUNC_FAILED, // 函数执行失败 + RECORDER_RESPONSE_MAX, + }; + +#define MAX_RECORDING_NUM 99 + typedef struct + { + char recordingFileName[32]; // 录音文件名 + char recordingDuration[16]; // 录音时长 + char recordingTime[16]; // 录音时间 + } RecordingInfo; + + class RecordingPlayerInterruptListener; + class RecordingModel + { + public: + static RecordingModel *GetInstance(void); + std::string GetRecordingPlayerUri(void); + void SetRecordingPlayerUri(std::string src); + void SetRecordingPlayButtonState(bool state); + void SetCircleProgress(int value); + int GetCircleProgress(void); + void AudioInit(void); + void ConvertMillisecondToTime(int32_t milliseconds); + int RecordingListOnClickPlay(void); + int RecordingPlayerStat(void); + int GetRecordingPlayerState(void); + int RecordingPlayerStop(void); + int RecordingPlayerReset(void); + void PreviousPlayout(void); + void NextPlayout(void); + void ClearRecordingPlayer(void); + /* -------------------------------------------------------------------------- */ + void InitRecordingListItem(); + std::vector &GetRecordinglistItems(); + std::string GetCurrentPlayRecordingName(void); + std::string GetCurrentPlayRecordingName(std::string name); + int GetRecordingListNum(); + void SetRecordingListNum(int value); + std::string GetCleanFileName(const std::string &filePath); + void SearchFiles(const std::string &directory, std::vector &Recordings, int &mp3FileCount); + void SetClickRecordingIndex(int index_); + int GetClickRecordingIndex(void); + std::vector &GetFileNames(void); + void SetTotalRecordDuration(std::string time); + std::string GetTotalRecordDuration(void) const; + void UpdateRecordingInfo(); + void SetRecordFileName(std::string name); + std::string GetRecordFileName(void); + std::string Getyyyymmhhh_date(void); + std::string &Getyyyymmhhh_dateAndTotalRecordDuration(void); + std::shared_ptr GetRecordingPlayerIntrptListener(void); + void ClearActivateAudioInterrupt(void); + std::shared_ptr GetPlayerCtr(void); + void SetAudioInitStatus(bool value); + /* ----------------------------------- 定时器 ---------------------------------- */ + void Recording_StartTimer(uint32_t interval = 1000); + void Recording_StopTimer(void); + char *DisplayRecordDuration(void); + bool CreateRecordPlayDirectory(const char *path); + const char *GetRecordDirectory() const; + static std::string recordTempDuration; // 录音时长 + int RecordDataWriteToFile(std::string name); + int RecordDataReadToFile(std::string name); + void printfRecordData(); + void GetDuration(int64_t &duration); + void UpdateRecordProcess(); + int getMaxRecordingNumber(void); + void setMaxRecordingNumber(int number); + void SetCurView(int16_t viewNum); + int GetCurView(void); + int GetUsedRecordingTime(void); + bool CheckRecordingTimeOut(int time); + void CheckRecordingSpaceOut(void); + bool GetCheckRecordingSpaceOut(void); + void SendCheckRecordingSpaceOutCmd(void); + + private: + RecordingModel(); + RecordingModel(const RecordingModel &) = delete; + RecordingModel &operator=(const RecordingModel &) = delete; + virtual ~RecordingModel(); + + private: + int64_t DurationTime{0}; // 播放时长,单位ms + bool PlayButtonState{false}; // 播放按钮状态 + int CircleProgress{0}; // 播放进度 + bool IsActivateAudioInterrupt{false}; // 是否激活音频中断 + AudioSession SessionId; // 音频会话ID + AudioInterrupt interrupt; // 音频中断管理 + std::shared_ptr p_RecordingPlayerInterruptListener{nullptr}; // 录音播放器中断监听 + std::shared_ptr PlayerCtr{nullptr}; // Player类:提供了播放在线电影、离线电影以及流媒体的功能,比如播放本地电影和高级音频编码(AAC)流的功能。 + std::shared_ptr PlayerCallback{nullptr}; // 为媒体播放期间发生的事件和异常通知提供侦听器。 + std::string Uri; // 唯一标识一个资源的字符串。 + std::map Header; + std::shared_ptr Resource{nullptr}; // 提供函数来实现与资源相关的操作。 + bool isStopAndReset{false}; // 判断是否是停止还是重置状态 + bool audioInitStatus{false}; + /* -------------------------------------------------------------------------- */ + std::vector fileNames; // 录音文件名数组 + int RecordingMp3FileCount = 0; // 录音MP3数量 +#ifdef SINGLE_USER_PARTITION + const std::string directory = "/user/music/recording/"; // 录音目录 + const std::string recordInfoFile = "/user/music/recording/recordinfo.bin"; +#else + const std::string directory = "/user/userdata/recording/"; // 录音目录 + const std::string recordInfoFile = "/user/userdata/recording/recordinfo.bin"; +#endif + std::vector Recordings{0}; // 存放录音信息的动态数组 + std::string recordDuration; // 录音时长 + /* -------------------------------------------------------------------------- */ + int index; // 保存被点击录音的下标 + std::string recordFileName; // 录音文件名 + char *yyyymmhhh_date; // 保存年月日时间 + std::string TotalRecordDuration; // 保存录音的总时长 + std::string RecordingTimeAndDuration; // 录音日期和录音时长 + RecordingInfo info[MAX_RECORDING_NUM] = {0}; + RecordingInfo recordingInfo{0}; + std::string mergefileName; + int MaxRecordingNumber{0}; //要录取的最大录音编号 + /* -------------------------------------------------------------------------- */ + bool RecordingPlayerViewIsCreate{false}; + int curView{0}; + int usedRecordingTime{0};//已使用的录音总时长 + bool RecordingSpaceIsOut{false}; + }; +} + +#endif diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingModelC.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingModelC.h new file mode 100644 index 000000000..c50fceb00 --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingModelC.h @@ -0,0 +1,27 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-10-21 16:29:03 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-10-21 16:40:18 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/record/include/RecordingModelC.h + */ + + +#ifndef RECORDING_MODELC_H +#define RECORDING_MODELC_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" +{ +#endif +#endif +#include + void CheckRecordingSpaceOutC(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingNumLimitView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingNumLimitView.h new file mode 100644 index 000000000..ada727638 --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingNumLimitView.h @@ -0,0 +1,50 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-08-30 15:38:55 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-08-30 16:08:59 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/record/include/RecordingNumLimitView.h + */ +#ifndef _RECORDING_NUM_LIMIT_VIEW_ +#define _RECORDING_NUM_LIMIT_VIEW_ + +#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 *RECORDINGNUMLIMITVIEW = "RecordingNumLimitView"; + static constexpr const char *RECORDINGNUMLIMITBUTTONVIEW = "RecordingNumLimitButtonView"; + class RecordingNumLimitView + { + public: + struct LabelConfig + { + int16_t left; + int16_t top; + int16_t width; + int16_t height; + int16_t fontSize; // 字体大小 + int16_t lineHeigh; // 行高 + int16_t textId; // 文本id + uint8_t lineBreakMode; // 断行模式。 + }; + RecordingNumLimitView(); + ~RecordingNumLimitView(); + UIScrollView *RecordingNumLimitViewInit(void); + + private: + UILabelExt *CreateRecordingNumLimitLabel(LabelConfig &labelconfig); // 设置标签 + void ClearAll(void); + UIScrollView *scrollView{nullptr}; + UILabelExt *title{nullptr}; + UIImageView *image{nullptr}; + UILabelExt *note{nullptr}; + UILabelExt *goitlabel{nullptr}; + UIButton *goitbutton{nullptr}; + }; + +} +#endif diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingPlayerView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingPlayerView.h new file mode 100644 index 000000000..54e1186dd --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingPlayerView.h @@ -0,0 +1,100 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-08-05 15:20:03 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-09-06 10:20:35 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/record/include/RecordingPlayerView.h + */ +#ifndef RECORD_PLAY_VIEW_H +#define RECORD_PLAY_VIEW_H + + +#include "View.h" + +#include "components/ui_scroll_view.h" +#include "components/ui_image_view.h" +#include "components/ui_circle_progress.h" +#include "components/ui_checkbox.h" +#include "components/ui_label_ext.h" +#include "ui_resource_string.h" +#include "components/ui_button.h" +#define APP_RES_PATH "/user/res" +namespace OHOS +{ + + static constexpr const char *PNG_UNIVERSAL_PAUSE_IMAGE = APP_RES_PATH "/record/UNIVERSAL_PAUSE.bin"; // 暂停 + static constexpr const char *PNG_UNIVERSAL_PLAY_IMAGE = APP_RES_PATH "/record/UNIVERSAL_PLAY.bin"; // 播放 + static constexpr const char *PNG_RECORD_PLAY_BACKGROUND_IMAGE = APP_RES_PATH "/record/RECORD_PLAY_BACKGROUND.bin"; // 背景 + static constexpr const char *PNG_RECORD_PLAY_PROGRESS_BG_IMAGE = APP_RES_PATH "/record/RECORD_PROGRESS_BG.bin"; // 进度条背景 + static constexpr const char *PNG_RECORD_PLAY_PROVE_IMAGE = APP_RES_PATH "/record/RECORD_PLAY_PROVE.bin"; // 上一首 + static constexpr const char *PNG_RECORD_PLAY_NEXT_IMAGE = APP_RES_PATH "/record/RECORD_PLAY_NEXT.bin"; // 下一首 + static constexpr const char *PNG_RECORD_PLAY_DELETE_IMAGE = APP_RES_PATH "/record/RECORD_PLAY_DELETE.bin"; // 删除 + static constexpr const char *PNG_RECORD_PLAY_VOLUME_IMAGE = APP_RES_PATH "/record/RECORD_PLAY_VOLUME.bin"; // 音量 + class RecordingPlayerView + { + + public: + struct LabelConfig + { + int16_t left; + int16_t top; + int16_t width; + int16_t height; + int16_t fontSize; // 字体大小 + int16_t lineHeigh; // 行高 + const char *text; // 文本 + uint8_t lineBreakMode; // 断行模式。 + }; + struct ButtonConfig + { + int16_t x; + int16_t y; + int16_t w; + int16_t h; + const char *ViewId; + const char *ImageSrc; + }; + + RecordingPlayerView(); + virtual ~RecordingPlayerView(); + static RecordingPlayerView *GetInstance(void); + UIScrollView *RecordingPlayerViewInit(void); + void ClearAll(void); + UILabelExt *GetRecordingFileNameLabel(void); + UILabelExt *GetRecordingTimeAndDurationLabel(void); + UICheckBox *GetPlayerButton(void); + void SetPlayerButtonState(UICheckBox::UICheckBoxState state); + UICheckBox::UICheckBoxState GetPlayerButtonState(void); + void ResetComponentStatus(void); + UICircleProgress *GetPlayerProgressBar(void); + void SetPlayerProgressBarValue(int value); + + private: + UILabelExt *SetUpLabel(LabelConfig &labelconfig); // 设置标签 + UIButton *SetTheButton(ButtonConfig &buttonconfig, UIView::OnClickListener *clickListener); + bool SetUpScrollView(void); + bool SetUpRecordingPlayerViewLabel(void); + bool SetUpBackGround(void); + bool SetUpPlayerProgressBarBackGroud(); + bool SetUpPlayerProgressBar(void); + bool SetUpPlayPauseButton(void); + bool SetUpProveButton(void); + bool SetUpNextButton(void); + bool SetUpDeleteButton(void); + bool SetUpVolumeButton(void); + UIScrollView *RecordingPlayerViewScrollView{nullptr}; + UIImageView *RecordingPlayBackground{nullptr}; // 录音播放视图背景图片 + UILabelExt *RecordingFileName{nullptr}; // 录音文件名 + UILabelExt *RecordingTimeAndDuration{nullptr}; // 录音时间和时长 + UIImageView *PlayerProgressBarBackGround{nullptr}; // 录音播放进度条背景 + UICircleProgress *PlayerProgressBar{nullptr}; // 录音播放进度条 + UICheckBox *RecordingPlayPauseButton{nullptr}; // 录音播放或暂停按钮 + UIButton *RecordingPlayProveButton{nullptr}; // 上一首按钮 + UIButton *RecordingPlayNextButton{nullptr}; // 下一首按钮 + UIButton *RecordingPlayDeleteButton{nullptr}; // 删除按钮 + UIButton *RecordingPlayVolumeButton{nullptr}; // 音量按钮 + UIView::OnClickListener *buttonClick{nullptr}; + bool initViewStatus{false}; + }; +} // namespace OHOS +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingPresenter.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingPresenter.h new file mode 100644 index 000000000..936111c15 --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingPresenter.h @@ -0,0 +1,165 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-02-27 09:16:51 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-10-21 11:20:46 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/record/include/RecordingPresenter.h + */ + +#ifndef RECORD_PRESENTER_H +#define RECORD_PRESENTER_H + +#include "Presenter.h" +#include "RecordingView.h" +#include "KeyInputListener.h" +#include "common/key_code.h" +#include "record/include/RecordingModel.h" +#include "media_thread_adapt.h" +#include "ModelListenerSample.h" +#include "source.h" +#include "audio_manager.h" +#include "player.h" + +namespace OHOS +{ + + using OHOS::Media::Player; + using OHOS::Media::Source; + using namespace OHOS::Media; + using namespace Audio; + using Audio::AudioManager; + + /*正在录音视图*/ + static const char *RECORD_GOING_BUTTON_VIEWID = "RECORD_GOING_BUTTON"; // 停止录音按钮id + + /*录音视图*/ + static const char *RECORD_BUTTON = "RecordButton"; // 录音按钮id + + /*录音播放视图*/ + static const char *RECORD_PLAY_PAUSE_CHECKBOX_VIEWID = "RECORD_PLAY_PAUSE_CHECKBOX"; // 播放和暂停复选框视图id + static const char *RECORD_PLAY_PROVE_BUTTON_VIEWID = "RECORD_PLAY_PROVE_BUTTON"; // 上一首按钮的视图id + static const char *RECORD_PLAY_NEXT_BUTTON_VIEWID = "RECORD_PLAY_NEXT_BUTTON"; // 下一首按钮的视图id + static const char *RECORD_PLAY_DELETE_BUTTON_VIEWID = "RECORD_PLAY_DELETE_BUTTON"; // 删除按钮的视图id + static const char *RECORD_PLAY_VOLUME_BUTTON_VIEWID = "RECORD_PLAY_VOLUME_BUTTON"; // 音量按钮的视图id + static const char *RECORD_PLAY_PLAYERPROGRESSBAR = "RECORD_PLAY_PLAYERPROGRESSBAR"; // 播放进度条视图id + + /*录音删除视图*/ + static const char *RECORD_DELETE_ON_BUTTON_VIEWID = "RECORD_DELETE_ON_BUTTON"; // 录音删除 + static const char *RECORD_DELETE_OFF_BUTTON_VIEWID = "RECORD_DELETE_OFF_BUTTON"; // 录音不删除 + + // 播放器中断监听 + class RecordingPlayerInterruptListener : public InterruptListener + { + public: + RecordingPlayerInterruptListener(); + ~RecordingPlayerInterruptListener(); + + void SetOwner(std::shared_ptr player); + void SetPaused(bool value); + void SetResumed(bool value); + void ResetFlag(); + bool IsPaused(); + bool IsDelayed(); + bool IsResumed(); + bool IsBeginStopped(); + bool IsEndStopped(); + void OnInterrupt(int32_t type, int32_t hint) override; + void PausePlayer(void); + void ResumePlayer(void); + void StopPlayer(void); + std::shared_ptr GetPlayer(); + + private: + std::shared_ptr player_{nullptr}; + bool isPaused_{false}; // 是否处于暂停状态 + bool isDelayed_{false}; // 是否处于延迟状态 + bool isResumed_{false}; // 是否已恢复播放状态 + bool isBeginStopped_{false}; // 是否处于已开始停止状态 + bool isEndStopped_{false}; // 是否处于已结束停止状态 + }; + + // 播放器回调 + class RecordingPlayerCallbackImpl : public OHOS::Media::PlayerCallback + { + public: + RecordingPlayerCallbackImpl(); + ~RecordingPlayerCallbackImpl(); + void OnPlaybackComplete(); + void OnError(int32_t errorType, int32_t errorCode); + void OnInfo(int type, int extra); + void OnRewindToComplete(); + + private: + }; + + /* + *录音播放器界面点击监听类 + */ + class RecordingPlayerViewOnClickListener : public UIView::OnClickListener + { + public: + RecordingPlayerViewOnClickListener() {} + + ~RecordingPlayerViewOnClickListener() {} + + bool OnClick(UIView &view, const ClickEvent &event) override; + void PlayerButtonOnClick(void); + }; + + /* + *录音列表视图监听类 + */ + class RecordListViewListener : public UIView::OnClickListener, public UIView::OnDragListener + { + public: + RecordListViewListener() {} + ~RecordListViewListener() {} + + 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}; + }; + + class RecordingModel; + class RecordingView; + class RecordingPresenter : public Presenter, + public UIView::OnClickListener, + public RootView::OnKeyActListener, + public UIView::OnDragListener, + public ModelListenerSample + { + public: + RecordingPresenter(); + virtual ~RecordingPresenter(); + + void OnStart() override; + void OnPause() override; + void OnResume() override; + void OnStop() override; + + static RecordingPresenter *GetInstance(); + int convertNumericDateTime(const char *numericDateTime, char *formattedDateTime); + void UpdateRecordProcess(); + void StopRecord(void); + void showWarning(void); + + private: + // 因为继承了OnClickListener,所以有OnClick属性,至于参数,原函数也这样直接继承; + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView &view, const DragEvent &event) override; + bool OnDragEnd(UIView &view, const DragEvent &event) override; + bool OnKeyAct(UIView &view, const KeyEvent &event) override; + void Notify() override; + void SetCircleProgress(); + void StartRecord(void); + // void StopRecord(void); + RecordingModel *p_RecordingModel{nullptr}; + uint8_t state_ = UICheckBox::UICheckBoxState::MAX_STATUS_NUM; + int64_t playerCurrentTime_{0}; + int64_t playerMusicDuration_{0}; + int64_t playerProgressValue_{0}; + }; +} + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingView.h new file mode 100644 index 000000000..e2060e80f --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingView.h @@ -0,0 +1,103 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-03-30 09:14:38 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2025-02-24 17:44:19 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/record/include/RecordingView.h + */ +#ifndef RECORD_VIEW_H +#define RECORD_VIEW_H + + +#include "View.h" + +#include "components/ui_view_group.h" +#include "components/ui_scroll_view.h" +#include "components/ui_label.h" +#include "components/ui_label_ext.h" +#include "components/ui_image_view.h" +#include "components/ui_button.h" +#include "components/ui_image_animator.h" + +#include "record/include/RecordListView.h" +#include "record/include/RecordGoingView.h" +#include "record/include/RecordingPlayerView.h" +#include "record/include/RecordDeleteView.h" +#include "record/include/RecordingVolumeSettingView.h" +#include "record/include/RecordingNumLimitView.h" + +namespace OHOS +{ + typedef enum + { + RECORDINGVIEW = 0, // 录音视图(slice) + RECORDINGLISTVIEW, // 录音列表视图(subView) + RECORDGOINGVIEW, // 正在录音视图(subView) + RECORDINGPLAYERVIEW, // 录音播放视图(subView) + RECORDINGDELETEVIEW, // 录音删除视图(subView) + RECORDINGVOLUMESETTINGVIEW, // 声音设置视图(subView) + RECORDINGEXCELIMIT, // 录音数量超出限制(subView) + MAX_RECORDINGVIEWID, + } RECORDINGVIEWID; + + class RecordingPresenter; + class RecordingView : public View + { + public: + struct ButtonConfig + { + int16_t x; + int16_t y; + int16_t w; + int16_t h; + const char *ViewId; + const char *ImageSrc; + }; + + RecordingView(); + virtual ~RecordingView(); + static RecordingView *GetInstance(void); + + bool ChangeRecordingView(int16_t thisView); // 切换到“录音”视图slice + bool ChangeRecordListView(int16_t thisView); // 切换到"录音列表"视图 + bool ChangeRecordGoingView(int16_t thisView); // 切换到“正在录音”视图 + bool ChangeRecordingPlayerView(int16_t thisView); // 切换到“录音播放”视图 + bool ChangeRecordDeleteView(int16_t thisView); // 切换到“录音删除”视图 + bool ChangeRecordVolumeSettingView(int16_t thisView); // 切换到“声音设置”视图 + bool ChangeRecordNumLimitView(int16_t thisView); // 切换到“录音超出限制”视图 + bool ClickFunc(int16_t interface); + void ChangeView(int16_t hideView, int16_t showView); + int GetCurrentViewType(UIScrollView *view); + UIScrollView *GetRecordingViewScrollView(int index); + + public: + void OnStart() override; + + private: + RecordListView *p_RecordListView{nullptr}; + RecordGoingView *p_RecordGoingView{nullptr}; + RecordingPlayerView *p_RecordingPlayerView{nullptr}; + RecordDeleteView *p_RecordDeleteView{nullptr}; + RecordingVolumeSettingView *p_RecordingVolumeSettingView{nullptr}; + RecordingNumLimitView *p_RecordingNumLimitView{nullptr}; + + private: + bool RecordingScrollViewInit(void); + bool RecordingLabelViewInit(void); + bool RecordingButtonViewInit(void); + bool RecordingImageViewInit(void); + + void RecordingViewInit(void); + void ClearAll(void); + UIButton *SetTheButton(ButtonConfig &buttonconfig, UIView::OnClickListener *clickListener); + UIScrollView *RecordingViewScrollView[MAX_RECORDINGVIEWID]{nullptr}; + UILabelExt *RecordingViewTitleLabel{nullptr}; + UIButton *RecordingViewButton{nullptr}; + UILabelExt *AttentionLabel{nullptr}; + UIImageAnimatorView *RecordingViewImageAnimator{nullptr}; + UIImageView *RECORD1_Image = nullptr; + UIImageView *pullUp_Image = nullptr; + }; +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingVolumeSettingView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingVolumeSettingView.h new file mode 100644 index 000000000..a4aaf684a --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/include/RecordingVolumeSettingView.h @@ -0,0 +1,31 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-03-13 17:34:03 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-06-13 11:21:14 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/record/include/RecordingVolumeSettingView.h + */ +#ifndef RECORDING_VOLUME_SETTING_VIEW_H +#define RECORDING_VOLUME_SETTING_VIEW_H + +#include "soundandvibration/include/SoundAndVibrationVolumeSettingView.h" +#include "components/ui_scroll_view.h" +namespace OHOS +{ + class RecordingVolumeSettingView + { + public: + RecordingVolumeSettingView(); + ~RecordingVolumeSettingView(); + static RecordingVolumeSettingView *GetInstance(); + UIScrollView *RecordingVolumeSettingViewInit(void); + void ClearAll(void); + private: + SoundAndVibrationVolumeSettingView *p_SoundAndVibrationVolumeSettingView{nullptr}; + UIScrollView *RecordingVolumeSettingViewScrollView{nullptr}; + bool initViewStatus{false}; + }; + +} + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordDeleteView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordDeleteView.cpp new file mode 100644 index 000000000..b72a336d9 --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordDeleteView.cpp @@ -0,0 +1,235 @@ +#include "record/include/RecordDeleteView.h" +#include "record/include/RecordingPresenter.h" +#include "record/include/RecordingModel.h" +#include "wearable_log.h" +#include "ui_resource_string.h" +#include "ConfigModel.h" +namespace OHOS +{ + static RecordDeleteView *g_pRecordDeleteView{nullptr}; + + RecordDeleteView::RecordDeleteView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordDeleteView::RecordDeleteView"); + g_pRecordDeleteView = this; + } + + RecordDeleteView::~RecordDeleteView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordDeleteView::~RecordDeleteView"); + ClearAll(); + g_pRecordDeleteView = nullptr; + } + + RecordDeleteView *RecordDeleteView::GetInstance() + { + return g_pRecordDeleteView; + } + + void RecordDeleteView::ClearAll() + { + if (RecordDeleteViewScrollView != nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordDeleteView::ClearAll"); + RecordDeleteViewScrollView->RemoveAll(); + if (TitleLabel) + { + delete TitleLabel; + TitleLabel = nullptr; + } + if (AttentionLabel) + { + delete AttentionLabel; + AttentionLabel = nullptr; + } + if (DeleteNameLabel) + { + delete DeleteNameLabel; + DeleteNameLabel = nullptr; + } + if (RECORD_DELETE_ON_BUTTON) + { + delete RECORD_DELETE_ON_BUTTON; + RECORD_DELETE_ON_BUTTON = nullptr; + } + if (RECORD_DELETE_OFF_BUTTON) + { + delete RECORD_DELETE_OFF_BUTTON; + RECORD_DELETE_OFF_BUTTON = nullptr; + } + if (RecordDeleteViewScrollView) + { + delete RecordDeleteViewScrollView; + RecordDeleteViewScrollView = nullptr; + } + } + } + + UILabelExt *RecordDeleteView::CreateRecordDeleteLabel(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->SetText(labelconfig.text); // 内容 + 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(23); + + return label; + } + + bool RecordDeleteView::RecordDeleteScrollViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordDeleteView::RecordDeleteScrollViewInit"); + RecordDeleteViewScrollView = new UIScrollView(); + if (RecordDeleteViewScrollView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordDeleteView::RecordDeleteViewScrollView new fail!"); + return false; + } + RecordDeleteViewScrollView->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + UIView::OnDragListener *dragListener = static_cast(RecordingPresenter::GetInstance()); + if (dragListener == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "dragListener is nullptr!!"); + return false; + } + RecordDeleteViewScrollView->SetOnDragListener(dragListener); + RecordDeleteViewScrollView->SetTouchable(true); + RecordDeleteViewScrollView->SetDraggable(true); + return true; + } + + bool RecordDeleteView::RecordDeleteLabelViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordDeleteView::RecordDeleteLabelViewInit"); + LabelConfig labelconfig = { + .left = 83, + .top = 50, + .width = 300, + .height = 35, + .fontSize = 30, + .lineHeigh = 35, + //.text = "删除录音", + .textId = STR_DELETE_RECORDING, + .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION, + }; + TitleLabel = CreateRecordDeleteLabel(labelconfig); + if (nullptr == TitleLabel) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordDeleteView::TitleLabel is nullptr!"); + return false; + } + RecordDeleteViewScrollView->Add(TitleLabel); + /* -------------------------------------------------------------------------- */ + labelconfig = { + .left = 53, + .top = 160, + .width = 360, + .height = 35, + .fontSize = 30, + .lineHeigh = 35, + //.text = "是否永久删除", + .textId = STR_DELETE_PERMANENTLY, + .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION, + }; + AttentionLabel = CreateRecordDeleteLabel(labelconfig); + if (nullptr == AttentionLabel) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordDeleteView::AttentionLabel is nullptr!"); + return false; + } + AttentionLabel->SetTextColor(Color::GetColorFromRGBA(0xff, 0x5a, 0x36, 0xff)); + RecordDeleteViewScrollView->Add(AttentionLabel); + /* -------------------------------------------------------------------------- */ + if (DeleteNameLabel == nullptr) + { + DeleteNameLabel = new UILabelExt(); + if (DeleteNameLabel == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordDeleteView::DeleteNameLabel is nullptr!"); + return false; + } + } + DeleteNameLabel->SetPosition(0, 0, 360, 35); // 位置大小 + DeleteNameLabel->SetStyle(STYLE_TEXT_FONT, 30); // 字体大小 + DeleteNameLabel->SetStyle(STYLE_LINE_HEIGHT, 35); // 字体行高 + DeleteNameLabel->SetText(""); // 内容 + DeleteNameLabel->SetLineBreakMode(UILabel::LINE_BREAK_OSCILLATION); // 断行模式。 + DeleteNameLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + DeleteNameLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, 30); + RecordDeleteViewScrollView->Add(DeleteNameLabel); + DeleteNameLabel->LayoutCenterOfParent(); // 与父视图中心对齐 + + return true; + } + + bool RecordDeleteView::RecordDeleteButtonViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordDeleteView::RecordDeleteButtonViewInit"); + UIView::OnClickListener *clickListener = static_cast(RecordingPresenter::GetInstance()); + if (clickListener == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "clickListener is nullptr!!"); + return false; + } + RECORD_DELETE_OFF_BUTTON = new UIButton(); + if (RECORD_DELETE_OFF_BUTTON == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordDeleteView::RECORD_DELETE_OFF_BUTTON is new fail!"); + return false; + } + RECORD_DELETE_OFF_BUTTON->SetPosition(111, 299, 100, 100); + RECORD_DELETE_OFF_BUTTON->SetViewId(RECORD_DELETE_OFF_BUTTON_VIEWID); + RECORD_DELETE_OFF_BUTTON->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919); + RECORD_DELETE_OFF_BUTTON->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff000000, UIButton::PRESSED); + RECORD_DELETE_OFF_BUTTON->SetImageSrc("/user/res/SYSTEM_CheckOff.bin", "/user/res/SYSTEM_CheckOff.bin"); + RECORD_DELETE_OFF_BUTTON->SetOnClickListener(clickListener); + RecordDeleteViewScrollView->Add(RECORD_DELETE_OFF_BUTTON); + /* -------------------------------------------------------------------------- */ + RECORD_DELETE_ON_BUTTON = new UIButton(); + if (RECORD_DELETE_ON_BUTTON == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordDeleteView::RECORD_DELETE_ON_BUTTON is new fail!"); + return false; + } + RECORD_DELETE_ON_BUTTON->SetPosition(256, 299, 100, 100); + RECORD_DELETE_ON_BUTTON->SetViewId(RECORD_DELETE_ON_BUTTON_VIEWID); + RECORD_DELETE_ON_BUTTON->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919); + RECORD_DELETE_ON_BUTTON->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff000000, UIButton::PRESSED); + RECORD_DELETE_ON_BUTTON->SetImageSrc("/user/res/SYSTEM_CheckOn.bin", "/user/res/SYSTEM_CheckOn.bin"); + RECORD_DELETE_ON_BUTTON->SetOnClickListener(clickListener); + RecordDeleteViewScrollView->Add(RECORD_DELETE_ON_BUTTON); + return true; + } + + UIScrollView *RecordDeleteView::RecordDeleteViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordDeleteViewInit"); + if (!RecordDeleteScrollViewInit() || !RecordDeleteLabelViewInit() || !RecordDeleteButtonViewInit()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordDeleteViewInit fail!!"); + return nullptr; + } + + return RecordDeleteViewScrollView; + } + + void RecordDeleteView::SetRecordDeleteName(const char *name) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordDeleteViewInit::SetRecordDeleteName"); + if (DeleteNameLabel) + { + mergefileName = RecordingModel::GetInstance()->GetCurrentPlayRecordingName(name); + DeleteNameLabel->SetText(mergefileName.c_str()); + DeleteNameLabel->Invalidate(); + } + } +} \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordGoingView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordGoingView.cpp new file mode 100644 index 000000000..dcc249379 --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordGoingView.cpp @@ -0,0 +1,275 @@ +#include "record/include/RecordGoingView.h" +#include "record/include/RecordingPresenter.h" +#include "UiConfig.h" +#include "wearable_log.h" +namespace OHOS +{ + + static RecordGoingView *g_pRecordGoingView{nullptr}; + + RecordGoingView::RecordGoingView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordGoingView::RecordGoingView"); + g_pRecordGoingView = this; + } + + RecordGoingView::~RecordGoingView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordGoingView::~RecordGoingView"); + ClearAll(); + g_pRecordGoingView = nullptr; + } + + RecordGoingView *RecordGoingView::GetInstance() + { + return g_pRecordGoingView; + } + + void RecordGoingView::ClearAll() + { + if (RecordGoingViewScrollView != nullptr) + { + RecordGoingViewScrollView->RemoveAll(); + + delete TitleLabel; + TitleLabel = nullptr; + + delete RECORD_GOING_IMAGE; + RECORD_GOING_IMAGE = nullptr; + + delete RECORD_GOING_BUTTON; + RECORD_GOING_BUTTON = nullptr; + + delete Timer; + Timer = nullptr; + + delete RecordGoingLabel; + RecordGoingLabel = nullptr; + + delete STOP_RECORD_GOING_BUTTON; + STOP_RECORD_GOING_BUTTON = nullptr; + + delete RecordGoingViewScrollView; + RecordGoingViewScrollView = nullptr; + } + } + + UILabel *RecordGoingView::GetRecordingDurationLabel(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordGoingView::GetRecordingDurationLabel"); + if (Timer == nullptr) + { + return nullptr; + } + return Timer; + } + + void RecordGoingView::AddViewsToScrollView(UIScrollView *scrollView, UIView *views[], int numViews) + { + for (int i = 0; i < numViews; ++i) + { + scrollView->Add(views[i]); + } + } + + void RecordGoingView::AddViewsToRecordGoingViewScrollView() + { + UIView *viewsToAdd[] = { + TitleLabel, + RECORD_GOING_IMAGE, + RECORD_GOING_BUTTON, + Timer, + RecordGoingLabel, + STOP_RECORD_GOING_BUTTON, + }; + + int numViews = sizeof(viewsToAdd) / sizeof(viewsToAdd[0]); + AddViewsToScrollView(RecordGoingViewScrollView, viewsToAdd, numViews); + } + + UILabel *RecordGoingView::CreateRecordGoingLabel(LabelConfig &labelconfig) + { + UILabel *label = new UILabel(); + 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->SetText(labelconfig.text); // 内容 + label->SetLineBreakMode(labelconfig.lineBreakMode); // 断行模式。 + label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, labelconfig.fontSize); + return label; + } + + UILabelExt *RecordGoingView::CreateRecordGoingLabelExt(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->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize); + return label; + } + + bool RecordGoingView::RecordGoingScrollViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordGoingView::RecordGoingScrollViewInit"); + RecordGoingViewScrollView = new UIScrollView(); + if (RecordGoingViewScrollView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordGoingView::RecordGoingViewScrollView new fail!"); + return false; + } + UIView::OnDragListener *draglistener = static_cast(RecordingPresenter::GetInstance()); + if (draglistener == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordGoingView::draglistener can not be nullptr!"); + return false; + } + RecordGoingViewScrollView->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + RecordGoingViewScrollView->SetTouchable(true); + RecordGoingViewScrollView->SetDraggable(true); + return true; + } + + bool RecordGoingView::RecordGoingLabelViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordGoingView::RecordGoingLabelViewInit"); + LabelConfig labelconfig = { + .left = 83, + .top = 50, + .width = 300, + .height = 35, + .fontSize = 30, + .lineHeigh = 35, + //.text = "录音机", + .textId = STR_RECORDER, + .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION, + }; + + TitleLabel = CreateRecordGoingLabelExt(labelconfig); + if (nullptr == TitleLabel) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordGoingView::TitleLabel is nullptr!"); + return false; + } + /* -------------------------------------------------------------------------- */ + labelconfig = { + .left = 83, + .top = 380, + .width = 300, + .height = 35, + .fontSize = 30, + .lineHeigh = 35, + //.text = "录音机", + .textId = STR_RECORDING, + .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION, + }; + RecordGoingLabel = CreateRecordGoingLabelExt(labelconfig); + if (nullptr == RecordGoingLabel) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordGoingView::RecordGoingLabel is nullptr!"); + return false; + } + + labelconfig = { + .left = 83, + .top = 300, + .width = 300, + .height = 77, + .fontSize = 65, + .lineHeigh = 76, + .text = "00:00:00", + .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION, + }; + Timer = CreateRecordGoingLabel(labelconfig); + if (nullptr == Timer) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordGoingView::Timer is nullptr!"); + return false; + } + + return true; + } + + bool RecordGoingView::RecordGoingImageViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordGoingView::RecordGoingImageViewInit"); + RECORD_GOING_IMAGE = new UIImageView(); + if (RECORD_GOING_IMAGE == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordGoingView::RECORD_GOING_IMAGE is nullptr!"); + return false; + } + RECORD_GOING_IMAGE->SetPosition(158, 129, 150, 150); + RECORD_GOING_IMAGE->SetStyle(STYLE_BACKGROUND_OPA, 0xff); + RECORD_GOING_IMAGE->SetStyle(STYLE_BORDER_RADIUS, 15); + RECORD_GOING_IMAGE->SetSrc(PNG_RECORD3_IMAGE); + + return true; + } + + bool RecordGoingView::RecordGoingButtonViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordGoingView::RecordGoingButtonViewInit"); + RECORD_GOING_BUTTON = new UIButton(); + if (RECORD_GOING_BUTTON == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordGoingView::RECORD_GOING_BUTTON new fail!"); + return false; + } + RECORD_GOING_BUTTON->SetPosition(210, 180, 60, 60); + RECORD_GOING_BUTTON->SetStyle(STYLE_BACKGROUND_COLOR, 0xffff5a36); + RECORD_GOING_BUTTON->SetStyle(STYLE_BORDER_RADIUS, 20); + RECORD_GOING_BUTTON->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xffff5a36, UIButton::PRESSED); + RECORD_GOING_BUTTON->SetStyleForState(STYLE_BORDER_RADIUS, 20, UIButton::PRESSED); + /* -------------------------------------------------------------------------- */ + STOP_RECORD_GOING_BUTTON = new UIButton(); + if (STOP_RECORD_GOING_BUTTON == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordGoingView::STOP_RECORD_GOING_BUTTON new fail!"); + return false; + } + STOP_RECORD_GOING_BUTTON->SetPosition(158, 129, 150, 150); + STOP_RECORD_GOING_BUTTON->SetViewId(RECORD_GOING_BUTTON_VIEWID); + STOP_RECORD_GOING_BUTTON->SetStyle(STYLE_BACKGROUND_COLOR, 0xffff5a36); + STOP_RECORD_GOING_BUTTON->SetStyle(STYLE_BACKGROUND_OPA, 0x00); + STOP_RECORD_GOING_BUTTON->SetStyleForState(STYLE_BACKGROUND_OPA, 0x00, UIButton::PRESSED); + UIView::OnClickListener *clickListener = static_cast(RecordingPresenter::GetInstance()); + STOP_RECORD_GOING_BUTTON->SetOnClickListener(clickListener); + + return true; + } + + UIScrollView *RecordGoingView::RecordGoingViewInit() + { + if (!RecordGoingScrollViewInit() || !RecordGoingLabelViewInit() || + !RecordGoingImageViewInit() || !RecordGoingButtonViewInit()) + { + return nullptr; + } + +#if 1 + AddViewsToRecordGoingViewScrollView(); +#else + RecordGoingViewScrollView->Add(TitleLabel); + RecordGoingViewScrollView->Add(RECORD_GOING_IMAGE); + RecordGoingViewScrollView->Add(RECORD_GOING_BUTTON); + RecordGoingViewScrollView->Add(Timer); + RecordGoingViewScrollView->Add(RecordGoingLabel); + RecordGoingViewScrollView->Add(STOP_RECORD_GOING_BUTTON); +#endif + return RecordGoingViewScrollView; + } + +} \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordListView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordListView.cpp new file mode 100644 index 000000000..330f48c50 --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordListView.cpp @@ -0,0 +1,306 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-02-27 09:16:50 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-11-05 14:39:41 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/record/src/RecordListView.cpp + */ + +#include "record/include/RecordListView.h" +#include "record/include/RecordingPresenter.h" +#include "wearable_log.h" +#include "record/include/RecordingModel.h" +namespace OHOS +{ + + static RecordListView *g_pRecordListView{nullptr}; + RecordListView::RecordListView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordListView::RecordListView"); + g_pRecordListView = this; + } + + RecordListView::~RecordListView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordListView::~RecordListView"); + ClearAll(); + g_pRecordListView = nullptr; + } + + RecordListView *RecordListView::GetInstance() + { + return g_pRecordListView; + } + + void RecordListView::ClearAll() + { + if (RecordListScrollView != nullptr) + { + // 首先移除所有子视图 + RecordListScrollView->RemoveAll(); + if (RecordListViewAttentionLabel != nullptr) + { + delete RecordListViewAttentionLabel; + RecordListViewAttentionLabel = nullptr; + } + if (RecordListViewTitleLabel != nullptr) + { + delete RecordListViewTitleLabel; + RecordListViewTitleLabel = nullptr; + } + if (p_RecordingListAdapter != nullptr) + { + delete p_RecordingListAdapter; + p_RecordingListAdapter = nullptr; + } + // 释放点击监听器 + if (UIView::OnClickListener *clicklister = recordList->GetOnClickListener()) + { + delete clicklister; + clicklister = nullptr; + } + // 释放拖动监听器 + if (UIView::OnDragListener *dragLister = RecordListScrollView->GetOnDragListener()) + { + delete dragLister; + dragLister = nullptr; + } + if (clickListener != nullptr) + { + delete clickListener; + clickListener = nullptr; + } + // 最后释放 RecordListScrollView 及其子视图 + if (recordList != nullptr) + { + delete recordList; + recordList = nullptr; + } + if (RecordListScrollView != nullptr) + { + delete RecordListScrollView; + RecordListScrollView = nullptr; + } + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ClearAll"); + } + } + + // 添加录音到list + void RecordListView::AddRecordingToList(const RecordingListItem &item) + { + if (p_RecordingListAdapter != nullptr) + { + p_RecordingListAdapter->AddListItem(item); + } + } + + // 把录音信息数据拿到存储到list中 + void RecordListView::InitRecordingInfo(void) + { + std::vector &item = RecordingModel::GetInstance()->GetRecordinglistItems(); + for (int i = 0; i < item.size(); i++) + { + AddRecordingToList(item[i]); + } + } + + // 每次录音完将数据刷新显示到list + void RecordListView::RefreshRecordingListData(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordListView::RefreshRecordingListData"); + RecordingModel::GetInstance()->InitRecordingListItem(); + int num = RecordingModel::GetInstance()->GetRecordingListNum(); + if (p_RecordingListAdapter != nullptr && recordList != nullptr) + { + if (num == 0) + { + IsVisibleLabel(true); + } + else + { + /* -------------------------------------------------------------------------- */ + IsVisibleLabel(false); + /* -------------------------------------------------------------------------- */ + if (num == 1) + { + recordList->SetHeight(120 * num); + } + else if (num == 2) + { + recordList->SetHeight(120 * num); + } + else + { + recordList->SetHeight(340); + } + p_RecordingListAdapter->ClearData(); + InitRecordingInfo(); + recordList->RefreshList(); + recordList->Invalidate(); + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordListView::RefreshRecordingListData over!!"); + } + return; + } + + // 设置提醒标签是否可见 + void RecordListView::IsVisibleLabel(bool value) + { + if (RecordListViewAttentionLabel && recordList) + { + if (value == true) + { + RecordListViewAttentionLabel->SetVisible(true); + recordList->SetVisible(false); // 列表设置不可见 + } + else + { + RecordListViewAttentionLabel->SetVisible(false); + recordList->SetVisible(true); // 列表设置可见 + } + } + } + + UILabelExt *RecordListView::CreateRecordListLabel(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->SetText(labelconfig.text); // 内容 + label->SetTextId(labelconfig.textId); + label->SetLineBreakMode(labelconfig.lineBreakMode); // 断行模式。 + label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize); + return label; + } + + bool RecordListView::RecordListScrollViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordListView::RecordListScrollViewInit"); + RecordListScrollView = new UIScrollView(); + if (RecordListScrollView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordListScrollView new fail!"); + return false; + } + RecordListScrollView->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + UIView::OnDragListener *draglistener = static_cast(new RecordListViewListener()); + if (draglistener == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "draglistener can not be nullptr!"); + return false; + } + RecordListScrollView->SetViewId(RECORDLISTSCROLLVIEW); + RecordListScrollView->SetOnDragListener(draglistener); + RecordListScrollView->SetTouchable(true); + RecordListScrollView->SetDraggable(true); + + return true; + } + + bool RecordListView::RecordListLabelViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordListView::SetUpRecordListViewLabel"); + LabelConfig labelconfig = { + .left = 83, + .top = 50, + .width = 300, + .height = 35, + .fontSize = 30, + .lineHeigh = 35, + .textId = STR_RECORDING_LIST, // 录音列表 + .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION, + }; + + RecordListViewTitleLabel = CreateRecordListLabel(labelconfig); + if (nullptr == RecordListViewTitleLabel) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordListViewTitleLabel is nullptr!"); + return false; + } + + labelconfig = { + .left = 53, + .top = 280, + .width = 360, + .height = 35, + .fontSize = 30, + .lineHeigh = 35, + .textId = STR_CRLEMPTY, // 当前录音列表为空 + .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION, + }; + RecordListViewAttentionLabel = CreateRecordListLabel(labelconfig); + if (nullptr == RecordListViewAttentionLabel) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordListViewAttentionLabel is nullptr!"); + return false; + } + RecordListViewAttentionLabel->SetTextColor(Color::GetColorFromRGBA(0x99, 0x99, 0x99, 0xff)); + + RecordListScrollView->Add(RecordListViewTitleLabel); + RecordListScrollView->Add(RecordListViewAttentionLabel); + + return true; + } + + bool RecordListView::RecordListListViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordListView::RecordListViewInit"); + if (p_RecordingListAdapter == nullptr) + { + p_RecordingListAdapter = new RecordingListAdapter(); + if (p_RecordingListAdapter == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordListView::p_RecordingListAdapter is nullptr!"); + return false; + } + clickListener = static_cast(new RecordListViewListener()); + if (clickListener == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordListView::clickListener is nullptr!"); + return false; + } + p_RecordingListAdapter->SetItemClickListener(clickListener); + } + if (recordList == nullptr) + { + recordList = new UIList(); + if (recordList == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordListView::recordList is nullptr!"); + return false; + } + } + recordList->SetPosition(43, 100, 380, 330); + recordList->SetStyle(STYLE_BACKGROUND_COLOR, 0xff000000); + recordList->SetThrowDrag(true); // 设置手指抬起屏幕后是否继续滚动。 + recordList->SetTouchable(true); + recordList->SetDraggable(true); + recordList->SetMaxScrollDistance(1000); // 设置手指抬起屏幕后的最大滚动距离。 + recordList->SetDragACCLevel(5); + recordList->SetSwipeACCLevel(200); /*设置手指抬起屏幕后的补偿距离。*/ + // recordList->SetReboundSize(30); + // recordList->SetScrollBlankSize(20); + // recordList->SetIntercept(true); // 设置是否拦截输入事件。如果被截获,视图在本地处理后不会将输入事件传递给父视图。 + recordList->SetAdapter(p_RecordingListAdapter); + RecordListScrollView->Add(recordList); + return true; + } + + UIScrollView *RecordListView::RecordListViewInit() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView::RecordListViewInit"); + // 如果其中任何一个初始化函数返回 false(即初始化失败),则会打印错误日志并返回空指针。 + if (!RecordListScrollViewInit() || !RecordListLabelViewInit() || !RecordListListViewInit()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordListViewInit fail!!"); + return nullptr; + } + return RecordListScrollView; + } +} \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingListAdapter.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingListAdapter.cpp new file mode 100644 index 000000000..1e8faa61c --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingListAdapter.cpp @@ -0,0 +1,93 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-08-05 15:20:03 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-10-09 18:11:09 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/record/src/RecordingListAdapter.cpp + */ +#include "record/include/RecordingListAdapter.h" +#include "record/include/RecordingListitemView.h" +namespace OHOS +{ + + RecordingListAdapter::RecordingListAdapter() + { + } + + RecordingListAdapter::~RecordingListAdapter() + { + listData.clear(); + } + + uint16_t RecordingListAdapter::GetCount(void) + { + return listData.size(); + } + + void RecordingListAdapter::SetData(std::list &data) + { + if (!listData.empty()) + { + listData.clear(); + } + std::list::iterator it; + for (it = data.begin(); it != data.end(); it++) + { + listData.push_back(*it); + } + } + + void RecordingListAdapter::ClearData(void) + { + if (!listData.empty()) + { + listData.clear(); + } + } + + UIView *RecordingListAdapter::GetView(UIView *inView, int16_t 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::iterator it = listData.begin(); + for (int i = 0; i < index; i++) + { + it++; + } + RecordingListItem itemData = *it; + RecordingListitemView *item = nullptr; + // 5.根据传入的inView参数是否已经存在一个视图对象,若为空则创建一个新的RecordingListItemView对象,否则将inView转换成RecordingListItemView类型的指针 + if (inView == nullptr) + { + item = new RecordingListitemView(); + } + else + { + item = static_cast(inView); + } + item->SetViewIndex(index); + item->SetItemInfo(itemData); + item->SetOnClickListener(itemClickListener); + return item; + } + + void RecordingListAdapter::AddListItem(const RecordingListItem &item) + { + listData.push_back(item); + } +} \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingListitemView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingListitemView.cpp new file mode 100644 index 000000000..86b799543 --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingListitemView.cpp @@ -0,0 +1,87 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-03-02 20:10:18 + * @LastEditors: SnickerSun snickersun@163.com + * @LastEditTime: 2024-10-10 21:51:20 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/record/src/RecordingListitemView.cpp + */ +#include "record/include/RecordingListitemView.h" +#include "record/include/RecordingModel.h" +#include "wearable_log.h" + +namespace OHOS +{ + + RecordingListitemView::RecordingListitemView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingListitemView::RecordingListitemView"); + SetPosition(0, 0, 380, 120); + SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + SetStyle(STYLE_BACKGROUND_OPA, 255); + SetTouchable(true); + SetUpChild(); + Add(&m_button); + Add(&m_recordId); + Add(&m_recordTotalTime); + Add(&m_recordTime); + } + + RecordingListitemView::~RecordingListitemView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingListitemView::~RecordingListitemView"); + Remove(&m_button); + Remove(&m_recordId); + Remove(&m_recordTotalTime); + Remove(&m_recordTime); + } + + void RecordingListitemView::SetItemInfo(const RecordingListItem itemInfo) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingListitemView::SetItemInfo"); + m_ItemInfo = itemInfo; + m_recordId.SetText(itemInfo.recordId.c_str()); + m_recordTotalTime.SetText(itemInfo.recordTotalTime); + m_recordTime.SetText(itemInfo.recordTime); + //防止list中元素超过3个后最后一个被遮住,且仅在最后一个元素设置其高度为160 + if (RecordingModel::GetInstance()->GetRecordingListNum() > 2 && GetViewIndex() == RecordingModel::GetInstance()->GetRecordingListNum() - 1) + { + SetHeight(160); + } + else + { + SetHeight(120); + } + } + + void RecordingListitemView::SetUpChild() + { + OHOS::ColorType textColor = Color::GetColorFromRGBA(0xcc, 0xcc, 0xcc, 0xcc); + OHOS::ColorType subTextColor = Color::GetColorFromRGBA(0x66, 0x66, 0x66, 0xff); + + m_button.SetPosition(0, 0, 380, 100); + m_button.SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919); + m_button.SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff383838, UIButton::PRESSED); + + SetLabelStyle(m_recordId, 35, 33, 96, 35, textColor, 25); + SetLabelStyle(m_recordTotalTime, 268, 19, 73, 35, textColor, 25); + SetLabelStyle(m_recordTime, 247, 57, 94, 23, subTextColor, 20); + } + + void RecordingListitemView::SetLabelStyle(UILabel &label, int x, int y, int width, int height, OHOS::ColorType textColor, int fontSize) + { + label.SetPosition(x, y, width, height); + label.SetTextColor(textColor); + label.SetStyle(STYLE_TEXT_FONT, fontSize); + label.SetStyle(STYLE_LINE_HEIGHT, height); + label.SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + label.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + label.SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, fontSize); + } + + int RecordingListitemView::GetRecordingListIndex() + { + // return m_ItemInfo.index; + return GetViewIndex(); + } + +} \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingModel.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingModel.cpp new file mode 100644 index 000000000..d3fb59fbd --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingModel.cpp @@ -0,0 +1,1225 @@ +#include +#include "record/include/RecordingModel.h" +#include "record/include/RecordGoingView.h" +#include "record/include/RecordingPresenter.h" +#include "thread_adapter.h" +#include "UiConfig.h" +#include "bts_a2dp_source.h" +#include "audio_manager.h" +#include +#include "custom_utils.h" +#include +#include +#include +#include +#include +#include "ConfigModel.h" +#include "cstring" +#include "record/include/RecordingModelC.h" +#include "uiservice/include/ui_service.h" +#include "custom_runtime.h" +#include "vibrator_service.h" +#include + +#ifdef FD230_650 +#include "system/include/SystemLogModel.h" +#endif + +namespace OHOS +{ + std::string RecordingModel::recordTempDuration = 0; + // 声明定时器变量 + osTimerId_t g_timer = NULL; + static int g_RecordingTimes = {0}; + static constexpr int32 NUM_TEN = 10; + static constexpr int16 ERROR = 0; + static constexpr int16 SUCCESS = 1; + static constexpr int16 NUM_TIME_MIN = 60; + static constexpr int16 NUM_TIME_HOUR = 3600; + static constexpr int32 NUM_TIME_DAY = 86400; + const int TOTAL_RECORDING_TIME = 20 * 60; // 20 分钟换算为秒 + static MutexId g_mutex; + RecordingModel::RecordingModel() + { + CreateRecordPlayDirectory(directory.c_str()); + } + + RecordingModel::~RecordingModel() {} + + RecordingModel *RecordingModel::GetInstance(void) + { + static RecordingModel instance; + return &instance; + } + + /* + * @brief 获取录音播放器Uri + * @return 文件路径 + */ + std::string RecordingModel::GetRecordingPlayerUri(void) + { + return Uri; + } + + /* + * @brief 设置录音播放器Uri + * @param src 文件路径 + */ + void RecordingModel::SetRecordingPlayerUri(std::string src) + { + Uri = src; + } + + /* + * @brief 设置录音播放按钮状态 + * @param state true 开启 + * @param state false 关闭 + */ + void RecordingModel::SetRecordingPlayButtonState(bool state) + { + PlayButtonState = state; + } + + /* + * @brief 设置播放进度 + */ + void RecordingModel::SetCircleProgress(int value) + { + CircleProgress = value; + } + + /* + * @brief 获取播放进度 + */ + int RecordingModel::GetCircleProgress(void) + { + return CircleProgress; + } + + /* + * @brief 获取录音播放器中断监听类 + */ + std::shared_ptr RecordingModel::GetRecordingPlayerIntrptListener(void) + { + return p_RecordingPlayerInterruptListener; + } + + /* + * @brief 清除音频中断 + */ + void RecordingModel::ClearActivateAudioInterrupt(void) + { + IsActivateAudioInterrupt = false; + } + + std::shared_ptr RecordingModel::GetPlayerCtr(void) + { + return PlayerCtr; + } + + /* + * @brief 设置是否音频已经初始化过 + */ + void RecordingModel::SetAudioInitStatus(bool value) + { + audioInitStatus = value; + } + + void RecordingModel::ClearRecordingPlayer(void) + { + RecordingPlayerStop(); // 录音播放器停止 + ClearActivateAudioInterrupt(); // 清除音频中断 + } + + /* + * @brief 初始化音频系统并准备播放器控制器和回调 + */ + void RecordingModel::AudioInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingModel::AudioInit"); + /* ---------- 检查一个成员变量 audioInitStatus 是否已经是 true。如果是,这表示音频已经初始化过了。 --------- */ + if (audioInitStatus == true) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "The audio has already been initialized!!"); + return; + } + AudioManager &amInstance = AudioManager::GetInstance(); + audioInitStatus = amInstance.Initialize(); + /* --------------------------- 步骤 1 播放器模块进行初始化并创建一个播放实例 -------------------------- */ + PlayerCtr = std::make_shared(); + if (PlayerCtr == nullptr || PlayerCtr.get() == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PlayerCtr is nullptr!!"); + return; + } + /* -------------------------------- 播放器回调初始化 -------------------------------- */ + PlayerCallback = std::make_shared(); + if (PlayerCallback.get() == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PlayerCallback new fail!!"); + return; + } + } + + /* + * @brief 将录音时长转换成时分秒 + */ + void RecordingModel::ConvertMillisecondToTime(int32_t milliseconds) + { + int seconds = (milliseconds / 1000) % 60; + int minutes = (milliseconds / (1000 * 60)) % 60; + int hours = milliseconds / (1000 * 60 * 60); + + if (hours == 0) + { + char buffer[10]; // 足够存放 "00:00\0" 的字符数组 + sprintf(buffer, "%02d:%02d", minutes, seconds); + SetTotalRecordDuration(buffer); + } + else + { + char buffer[12]; // 足够存放 "00:00:00\0" 的字符数组 + sprintf(buffer, "%02d:%02d:%02d", hours, minutes, seconds); + SetTotalRecordDuration(buffer); + } + } + + // 点击录音列表中录音播放 + int RecordingModel::RecordingListOnClickPlay(void) + { + SetRecordingPlayerUri(directory + GetCurrentPlayRecordingName() + ".mp3"); +#if 0 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingModel::RecordingListOnClickPlay"); + int ret; + int32_t playerState; + uint8_t state = UICheckBox::UICheckBoxState::MAX_STATUS_NUM; + RecordingPlayerView *p_RecordingPlayerView = RecordingPlayerView::GetInstance(); + if (p_RecordingPlayerView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "p_RecordingPlayerView null!"); + return OHOS_FAILURE; + } + SetRecordingPlayerUri(directory + GetCurrentPlayRecordingName() + ".mp3"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "uri: %s,line = %d", GetRecordingPlayerUri().c_str(), __LINE__); + + state = p_RecordingPlayerView->GetPlayerButtonState(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "state %d,line = %d", state, __LINE__); + + if (state == UICheckBox::UICheckBoxState::UNSELECTED) + { + p_RecordingPlayerView->SetPlayerButtonState(UICheckBox::UICheckBoxState::SELECTED); + SetRecordingPlayButtonState(true); + /* start play */ + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "play"); + playerState = GetRecordingPlayerState(); + if (playerState == PlayerStates::PLAYER_PAUSED || playerState == PlayerStates::PLAYER_PLAYBACK_COMPLETE) + { + ret = PlayerCtr->Reset(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Reset, ret:%d", ret); + } + RecordingPlayerStat(); // 播放 + } + else if (state == UICheckBox::UICheckBoxState::SELECTED) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "List to play"); + playerState = GetRecordingPlayerState(); + if (playerState == PlayerStates::PLAYER_STARTED) + { + ret = PlayerCtr->Stop(); // 停止 + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Stop, ret:%d", ret); + ret = PlayerCtr->Reset(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Reset, ret:%d", ret); + } + RecordingPlayerStat(); + } +#endif + return OHOS_SUCCESS; + } + + // 录音播放 + int RecordingModel::RecordingPlayerStat() + { + /* ------------------------------ 每次新的播放进度都设为0 ------------------------------ */ + SetCircleProgress(0); // 0:进度100% + RecordingPlayerView *p_RecordingPlayerView = RecordingPlayerView::GetInstance(); + if (p_RecordingPlayerView != nullptr) + { + p_RecordingPlayerView->SetPlayerProgressBarValue(CircleProgress); + } + /* -------------------------------------------------------------------------- */ + int32_t ret; + + // 设置回调函数 + PlayerCtr->SetPlayerCallback(PlayerCallback); + // 添加条件判断,确保uri必须为MP3格式 + if (Uri.find(".mp3") == std::string::npos) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid file format. Only MP3 files are supported."); + return OHOS_FAILURE; + } + // 申请资源 + Resource = std::make_shared(Uri, Header); + if (Resource.get() == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Resource new fail"); + return OHOS_FAILURE; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Player uri %s.", Uri.c_str()); + ret = PlayerCtr->SetSource(*Resource); + if (ret != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetSource fail"); + PlayerCtr->Reset(); + return OHOS_FAILURE; + } + ret = PlayerCtr->Prepare(); + if (ret != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Prepare fail"); + PlayerCtr->Reset(); + return OHOS_FAILURE; + } + ret = PlayerCtr->GetDuration(DurationTime); + ConvertMillisecondToTime(DurationTime); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[%s,%d] GetDuration:%lld,%s, ret:%d", __func__, __LINE__, DurationTime, TotalRecordDuration.c_str(), ret); + /* -------------------------------------------------------------------------- */ + if (!IsActivateAudioInterrupt) + { + // 申请焦点 + AudioManager &amIntance = AudioManager::GetInstance(); + SessionId = amIntance.MakeSessionId(); + if (SessionId == AUDIO_SESSION_ID_NONE) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "session invalid"); + return OHOS_FAILURE; + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MakeSessionId %d", SessionId); + p_RecordingPlayerInterruptListener = std::make_shared(); + if (p_RecordingPlayerInterruptListener.get() == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "p_RecordingPlayerInterruptListener new fail"); + return OHOS_FAILURE; + } + p_RecordingPlayerInterruptListener->SetOwner(PlayerCtr); + interrupt = {AUDIO_STREAM_MUSIC, SessionId, p_RecordingPlayerInterruptListener}; + // 激活音频中断 5s超时 + if (amIntance.ActivateAudioInterrupt(interrupt) == INTERRUPT_FAILED) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ActivateAudioInterrupt faild"); + return OHOS_FAILURE; + } + IsActivateAudioInterrupt = true; + } + ret = PlayerCtr->SetAudioSessionId(SessionId); + if (ret != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetAudioSessionId faild"); + PlayerCtr->Reset(); + return OHOS_FAILURE; + } + // 播放 + ret = PlayerCtr->Play(); + if (ret != 0) + { + PlayerCtr->Stop(); // 暂停 + PlayerCtr->Reset(); // 初始化 + // RecordingPlayerView *p_RecordingPlayerView = RecordingPlayerView::GetInstance(); + if (p_RecordingPlayerView != nullptr) + { + p_RecordingPlayerView->SetPlayerButtonState(UICheckBox::UNSELECTED); + SetCircleProgress(0); // 0:进度0% + p_RecordingPlayerView->SetPlayerProgressBarValue(CircleProgress); + } + else + { + SetRecordingPlayButtonState(false); + SetCircleProgress(0); // 0:进度0% + } + AudioManager::GetInstance().DeactivateAudioInterrupt(interrupt); + IsActivateAudioInterrupt = false; + } + return OHOS_SUCCESS; + } + + /* + * @brief 获取录音播放器状态 + */ + int RecordingModel::GetRecordingPlayerState(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[RecordingModel] GetRecordingPlayerState"); + /* ------------------------------ 检查播放器控制对象是否为空 ----------------------------- */ + if (PlayerCtr.get() == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PlayerCtr.get() is nullptr!!"); + return OHOS_FAILURE; + } + int32_t state; + PlayerCtr->GetPlayerState(state); + return state; + } + + /* + * @brief 录音播放器停止 + */ + int RecordingModel::RecordingPlayerStop(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingModel::RecordingPlayerStop"); + int32_t state = GetRecordingPlayerState(); + if (state == OHOS_FAILURE) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Get state of player failed!!"); + return OHOS_FAILURE; + } + + if (state == PlayerStates::PLAYER_STARTED || state == PlayerStates::PLAYER_PLAYBACK_COMPLETE) + { + int ret = PlayerCtr->Stop(); + if (ret != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Stop err, ret:%d", ret); + return OHOS_FAILURE; + } + ret = PlayerCtr->Reset(); + if (ret != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Reset err, ret:%d", ret); + return OHOS_FAILURE; + } + else + { + isStopAndReset = true; + SetRecordingPlayButtonState(false); + SetCircleProgress(0); + if (RecordingPlayerView::GetInstance() != nullptr) + { + RecordingPlayerView::GetInstance()->SetPlayerButtonState(UICheckBox::UNSELECTED); + } + } + AudioManager::GetInstance().DeactivateAudioInterrupt(interrupt); + return OHOS_SUCCESS; + } + else if (state == PlayerStates::PLAYER_PAUSED) + { + int ret = PlayerCtr->Reset(); + if (ret != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Reset err, ret:%d", ret); + return OHOS_FAILURE; + } + else + { + SetRecordingPlayButtonState(false); + SetCircleProgress(0); + if (RecordingPlayerView::GetInstance() != nullptr) + { + RecordingPlayerView::GetInstance()->SetPlayerButtonState(UICheckBox::UNSELECTED); + } + } + if (AudioManager::GetInstance().DeactivateAudioInterrupt(interrupt) != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DeactivateAudioInterrupt err"); + return OHOS_FAILURE; + } + return OHOS_SUCCESS; + } + else if (state == PlayerStates::PLAYER_STOPPED) + { + return RECORDER_ALREADY_STOPPED; + } + return OHOS_SUCCESS; + } + + int RecordingModel::RecordingPlayerReset(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingModel::RecordingPlayerReset"); + int ret = PlayerCtr->Stop(); + if (ret != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Stop err, ret:%d", ret); + return OHOS_FAILURE; + } + ret = PlayerCtr->Reset(); + if (ret != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Reset err, ret:%d", ret); + return OHOS_FAILURE; + } + if (AudioManager::GetInstance().DeactivateAudioInterrupt(interrupt) != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DeactivateAudioInterrupt err"); + return OHOS_FAILURE; + } + IsActivateAudioInterrupt = false; + return OHOS_SUCCESS; + } + + /* + * @brief 上一首录音播放 + */ + void RecordingModel::PreviousPlayout(void) + { + int index = GetClickRecordingIndex(); + int num = GetRecordingListNum(); + if (num == 1) + { + return; // 只有一首录音 + } + RecordingPlayerView *p_RecordingPlayerView = RecordingPlayerView::GetInstance(); + if (p_RecordingPlayerView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "p_RecordingPlayerView null!"); + return; + } + + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "NextPlayout before index %d,filename %s", GetClickRecordingIndex(), GetCurrentPlayRecordingName().c_str()); + if ((index > num - 1) || (index < 0)) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "currentIndex err"); + SetClickRecordingIndex(0); + return; + } + SetClickRecordingIndex(--index < 0 ? num - 1 : index); // 如果从第一首录音设置上一首,那就跳到最后一首 + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "NextPlayout after index %d,filename %s", GetClickRecordingIndex(), GetCurrentPlayRecordingName().c_str()); + SetRecordingPlayerUri(directory + GetCurrentPlayRecordingName() + ".mp3"); + SetCircleProgress(0); + int32_t ret; + int32_t playerState; + PlayerCtr->GetPlayerState(playerState); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "playerState Value %d.", playerState); + if ((playerState == PlayerStates::PLAYER_STARTED) || (playerState == PlayerStates::PLAYER_PLAYBACK_COMPLETE)) + { + /* start play */ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "start play, 160."); + ret = PlayerCtr->Stop(); // 停止 + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Stop, ret:%d", ret); + ret = PlayerCtr->Reset(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Reset, ret:%d", ret); + + p_RecordingPlayerView->SetPlayerButtonState(UICheckBox::UICheckBoxState::SELECTED); + SetRecordingPlayButtonState(true); + + ret = RecordingPlayerStat(); // 播放 + if (ret != 0) + { + /* stop and exit */ + ret = PlayerCtr->Stop(); // 停止 + ret = PlayerCtr->Reset(); + } + } + else if (playerState == PlayerStates::PLAYER_PAUSED || (playerState == PlayerStates::PLAYER_IDLE)) + { + ret = PlayerCtr->Reset(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Reset, ret:%d", ret); + } + } + + /* + * @brief 下一首录音播放 + */ + void RecordingModel::NextPlayout(void) + { + int index = GetClickRecordingIndex(); + int num = GetRecordingListNum(); + if (num == 1) + { + return; // 只有一首录音 + } + RecordingPlayerView *p_RecordingPlayerView = RecordingPlayerView::GetInstance(); + if (p_RecordingPlayerView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "p_RecordingPlayerView null!"); + return; + } + + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "NextPlayout before index %d,filename %s", GetClickRecordingIndex(), GetCurrentPlayRecordingName().c_str()); + if ((index > num - 1) || (index < 0)) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "currentIndex err"); + SetClickRecordingIndex(0); + return; + } + SetClickRecordingIndex(++index > num - 1 ? 0 : index); // 如果从最后一首录音设置下一首,那就跳到第一首 + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "NextPlayout after index %d,filename %s", GetClickRecordingIndex(), GetCurrentPlayRecordingName().c_str()); + SetRecordingPlayerUri(directory + GetCurrentPlayRecordingName() + ".mp3"); + SetCircleProgress(0); + int32_t ret; + int32_t playerState; + PlayerCtr->GetPlayerState(playerState); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "playerState Value %d.", playerState); + if ((playerState == PlayerStates::PLAYER_STARTED) || (playerState == PlayerStates::PLAYER_PLAYBACK_COMPLETE)) + { + /* start play */ + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "start play, 160."); + ret = PlayerCtr->Stop(); // 停止 + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Stop, ret:%d", ret); + ret = PlayerCtr->Reset(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Reset, ret:%d", ret); + + p_RecordingPlayerView->SetPlayerButtonState(UICheckBox::UICheckBoxState::SELECTED); + SetRecordingPlayButtonState(true); + + ret = RecordingPlayerStat(); // 播放 + if (ret != 0) + { + /* stop and exit */ + ret = PlayerCtr->Stop(); // 停止 + ret = PlayerCtr->Reset(); + } + } + else if (playerState == PlayerStates::PLAYER_PAUSED || (playerState == PlayerStates::PLAYER_IDLE)) + { + ret = PlayerCtr->Reset(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Reset, ret:%d", ret); + } + } + + /* + * @brief 获取纯净.mp3后缀文件名 + * @param 文件路径 + * @return 返回纯净文件名 + */ + std::string RecordingModel::GetCleanFileName(const std::string &filePath) + { + size_t found = filePath.find_last_of("/\\"); + + std::string fileName = (found != std::string::npos) ? filePath.substr(found + 1) : filePath; + + if (fileName.size() >= 4 && fileName.substr(fileName.size() - 4) == ".mp3") + { + // 去除文件名的 .mp3 后缀 + return fileName.substr(0, fileName.size() - 4); + } + return ""; // 返回空字符串表示不是 .mp3 文件 + } + + static int timeToSeconds(const char *timeStr) + { + int minutes = 0; + int seconds = 0; + sscanf(timeStr, "%d:%d", &minutes, &seconds); + return minutes * 60 + seconds; + } + + /* + * @brief 搜索录音文件 + * @param -directory 录音文件目录 + * @param -fileNames 保存录音文件名的可变长数组 + * @param -mp3FileCount 录音文件数量 + * @return void + */ + void RecordingModel::SearchFiles(const std::string &directory, std::vector &Recordings, int &mp3FileCount) + { + DIR *dir; + struct dirent *ent; + if ((dir = opendir(directory.c_str())) != NULL) + { + while ((ent = readdir(dir)) != NULL) + { + std::string fileName = ent->d_name; + if (fileName != "." && fileName != "..") + { + std::string filePath = directory + fileName; + if (ent->d_type == DT_REG || ent->d_type == DT_UNKNOWN) // 普通文件 + { + std::string cleanFileName = GetCleanFileName(filePath); + if (!cleanFileName.empty()) + { + RecordDataReadToFile(cleanFileName.c_str()); + strcpy(info[mp3FileCount].recordingFileName, recordingInfo.recordingFileName); + strcpy(info[mp3FileCount].recordingDuration, recordingInfo.recordingDuration); + strcpy(info[mp3FileCount].recordingTime, recordingInfo.recordingTime); + usedRecordingTime += timeToSeconds(recordingInfo.recordingDuration); + mp3FileCount++; + } + } + else if (ent->d_type == DT_DIR) // 目录 + { + std::string subDirectory = directory + fileName + "/"; + SearchFiles(subDirectory, Recordings, mp3FileCount); // 递归搜索子目录 + } + } + } + closedir(dir); + } + // 使用冒泡排序进行排序 + for (int i = 0; i < mp3FileCount - 1; i++) + { + for (int j = 0; j < mp3FileCount - i - 1; j++) + { + int a = atoi(info[j].recordingFileName); + int b = atoi(info[j + 1].recordingFileName); + if (a < b) + { + RecordingInfo temp = info[j]; + info[j] = info[j + 1]; + info[j + 1] = temp; + } + } + } + } + + /* + * @brief 初始化录音列表数据 + */ + void RecordingModel::InitRecordingListItem(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingModel::InitRecordingListItem"); + /* ---------------------------------- 清空操作 --------------------------------- */ + if (!Recordings.empty()) + { + Recordings.clear(); + } + if (!fileNames.empty()) + { + fileNames.clear(); + } + for (int i = 0; i < RecordingMp3FileCount; ++i) + { + memset(info[i].recordingFileName, 0, sizeof(info[i].recordingFileName)); + memset(info[i].recordingDuration, 0, sizeof(info[i].recordingDuration)); + memset(info[i].recordingTime, 0, sizeof(info[i].recordingTime)); + } + RecordingMp3FileCount = 0; + MaxRecordingNumber = 0; + usedRecordingTime = 0; + /* -------------------------------------------------------------------------- */ + SearchFiles(directory, Recordings, RecordingMp3FileCount); + if (RecordingMp3FileCount != 0) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Total .mp3 Files Count:%d", RecordingMp3FileCount); + MaxRecordingNumber = atoi(info[0].recordingFileName); + for (int i = 1; i < RecordingMp3FileCount; i++) + { + if (atoi(info[i].recordingFileName) > MaxRecordingNumber) + { + MaxRecordingNumber = atoi(info[i].recordingFileName); + } + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MaxRecordingNumber:%d", MaxRecordingNumber); + // 对 Recordings 数组进行操作 + for (int i = 0; i < RecordingMp3FileCount; i++) + { + Recordings.push_back({i, GetCurrentPlayRecordingName(info[i].recordingFileName), info[i].recordingDuration, info[i].recordingTime}); + } + } + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingModel::InitRecordingListItem over!!"); + } + + /* + * @brief 获取存放录音的基本信息动态数组 + * @return 返回该动态数组 + */ + std::vector &RecordingModel::GetRecordinglistItems(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingModel::GetRecordinglistItems"); + return Recordings; + } + + /* + * @brief 获取当前播放的录音文件名 + */ + std::string RecordingModel::GetCurrentPlayRecordingName(void) + { + return info[GetClickRecordingIndex()].recordingFileName; + } + + std::string RecordingModel::GetCurrentPlayRecordingName(std::string name) + { + int language = ConfigModel::GetInstance()->GetLanguage(); + if (language == 0) // 如果当前系统为中文 + { + mergefileName = "录音 "; + mergefileName += name; + } + else + { + mergefileName = "Audio "; + mergefileName += name; + } + return mergefileName; + } + + /* + * @brief 获取年月日时间和录音时长 + */ + std::string &RecordingModel::Getyyyymmhhh_dateAndTotalRecordDuration(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[RecordingModel] Getyyyymmhhh_dateAndTotalRecordDuration"); + std::string yyyymmhhh_date = Recordings[GetClickRecordingIndex()].recordTime; + std::string TotalRecordDuration = Recordings[GetClickRecordingIndex()].recordTotalTime; + // 去掉日期字符串末尾的换行符 + if (!yyyymmhhh_date.empty() && yyyymmhhh_date.back() == '\n') + { + yyyymmhhh_date.erase(yyyymmhhh_date.length() - 1); + } + RecordingTimeAndDuration = (yyyymmhhh_date + "-" + TotalRecordDuration); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "recordTime = %s recordTotalTime = %s", yyyymmhhh_date.c_str(), TotalRecordDuration.c_str()); + return RecordingTimeAndDuration; + } + + /* + * @brief 获取录音数量 + */ + int RecordingModel::GetRecordingListNum(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingModel::GetRecordingListNum %d", RecordingMp3FileCount); + return RecordingMp3FileCount; + } + + // 设置录音数量 + void RecordingModel::SetRecordingListNum(int value) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingModel::GetRecordingListNum %d", value); + if (value > MAX_RECORDING_NUM) + { + RecordingMp3FileCount = MAX_RECORDING_NUM; + return; + } + RecordingMp3FileCount = value; + } + + /* + * @brief 保存被点击录音下标 + */ + void RecordingModel::SetClickRecordingIndex(int index_) + { + index = index_; + } + + /* + * @brief 获取被点击录音下标 + */ + int RecordingModel::GetClickRecordingIndex(void) + { + return index; + } + + /* + *@brief 获取保存文件名的动态数组 + */ + std::vector &RecordingModel::GetFileNames(void) + { + return fileNames; + } + + /* + * @brief 保存录音的总时长 + */ + void RecordingModel::SetTotalRecordDuration(std::string time) + { + TotalRecordDuration = time; + } + + /* + * @brief 获取录音时长 + */ + std::string RecordingModel::GetTotalRecordDuration(void) const + { + return TotalRecordDuration; + } + + /* + * @brief 获取录音年月日时间 + */ + std::string RecordingModel::Getyyyymmhhh_date(void) + { + char *yyyymmhhh_date_new = uapi_get_local_yyyymmdd_date(); // 获取日期 + if (yyyymmhhh_date_new == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get local date"); + return ""; // 或者进行适当的错误处理 + } + // 释放之前分配的日期字符串内存(如果之前有) + if (yyyymmhhh_date != nullptr) + { + free(yyyymmhhh_date); + } + // 更新日期字符串成员 + yyyymmhhh_date = yyyymmhhh_date_new; + return yyyymmhhh_date; + } + + void RecordingModel::UpdateRecordingInfo() + { + if (index < 0 || index > RecordingMp3FileCount) + { + return; + } + std::string delete_filename_mp3 = (directory + GetCurrentPlayRecordingName()).append(".mp3"); + std::string delete_filename_txt = (directory + GetCurrentPlayRecordingName()).append(".txt"); + /* -------------------------------- 删除录音文件 -------------------------------- */ + uapi_delete_files(delete_filename_mp3.c_str()); + uapi_delete_files(delete_filename_txt.c_str()); + /* -------------------------------------------------------------------------- */ + } + + // 设置当前的录音文件名,每次录音会更改 + void RecordingModel::SetRecordFileName(std::string name) + { + recordFileName = name; + } + + // 获取当前的录音文件名,每次录音会更改 + std::string RecordingModel::GetRecordFileName(void) + { + return recordFileName; + } + + void RecordingModel::GetDuration(int64_t &duration) + { + duration = DurationTime; + } + + void RecordingModel::UpdateRecordProcess() + { + if (RecordingPresenter::GetInstance()) + { + RecordingPresenter::GetInstance()->UpdateRecordProcess(); + } + } + + int RecordingModel::getMaxRecordingNumber(void) + { + return MaxRecordingNumber; + } + + void RecordingModel::setMaxRecordingNumber(int number) + { + MaxRecordingNumber = number; + } + + /*创建录音播放路径*/ + bool RecordingModel::CreateRecordPlayDirectory(const char *path) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingModel::CreateRecordPlayDirectory"); + if (access(path, F_OK) == -1) + { // 如果路径不存在 + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Directory %s not exist, creating directory", path); + if (mkdir(path, 0777) != 0) + { // 尝试创建目录,如果创建失败 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Create directory %s failed", path); + return false; + } + } + else + { // 如果路径存在 + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Directory %s already exists", path); + } + return true; + } + + // 获取录音目录 + const char *RecordingModel::GetRecordDirectory() const + { + return directory.c_str(); + } + + // 保存录音信息文件 + int RecordingModel::RecordDataWriteToFile(std::string name) + { + if (name.empty()) + { + return OHOS_FAILURE; + } + name = directory + name.append(".txt"); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[%d]:RecordDataWriteToFile %s", __LINE__, name.c_str()); + FILE *fp = fopen(name.c_str(), "wb+"); + if (nullptr == fp) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%d]:RecordDataWriteToFile fail", __LINE__); + return OHOS_FAILURE; + } + + std::string recordingFileName = GetRecordFileName(); // 录音文件名 + std::string yyymmhhh_date = Getyyyymmhhh_date(); // 保存录音年月日时间 + std::string TotalRecordDuration = RecordingModel::recordTempDuration; // 录音的总时长 + // recordingInfo = {0}; + memset(&recordingInfo, 0, sizeof(RecordingInfo)); + strncpy_s(recordingInfo.recordingFileName, 32, recordingFileName.c_str(), recordingFileName.length()); + strncpy_s(recordingInfo.recordingDuration, 16, TotalRecordDuration.c_str(), TotalRecordDuration.length()); + strncpy_s(recordingInfo.recordingTime, 16, yyymmhhh_date.c_str(), yyymmhhh_date.length()); + + size_t ret = fwrite((void *)&recordingInfo, sizeof(RecordingInfo), 1, fp); + fclose(fp); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[%d]:RecordDataWriteToFile success", __LINE__); + + return OHOS_SUCCESS; + } + + // 读取录音信息文件 + int RecordingModel::RecordDataReadToFile(std::string name) + { + if (name.empty()) + { + return OHOS_FAILURE; + } + name = directory + name.append(".txt"); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[%d]:RecordDataReadToFile %s", __LINE__, name.c_str()); + FILE *fp = fopen(name.c_str(), "rb"); + if (fp == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%d]:RecordDataReadToFile", __LINE__); + return OHOS_FAILURE; + } + fread((void *)&recordingInfo, sizeof(RecordingInfo), 1, fp); + printfRecordData(); + fclose(fp); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[%d]:RecordDataReadToFile success", __LINE__); + return OHOS_SUCCESS; + } + + void RecordingModel::printfRecordData() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "recordingFileName %s", recordingInfo.recordingFileName); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "recordingDuration %s", recordingInfo.recordingDuration); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "recordingTime %s", recordingInfo.recordingTime); + } + + /*设置当前哪个子视图是可见的*/ + void RecordingModel::SetCurView(int16_t viewNum) + { + curView = viewNum; + } + + /*获取当前哪个子视图是可见的*/ + int RecordingModel::GetCurView(void) + { + return curView; + } + int RecordingModel::GetUsedRecordingTime(void) + { + return usedRecordingTime; + } + + // 检查录音时间是否超时 + bool RecordingModel::CheckRecordingTimeOut(int time) + { + if (time >= TOTAL_RECORDING_TIME) + { + return true; + } + return false; + } + + // 检查录音空间是否满了 + void RecordingModel::CheckRecordingSpaceOut(void) + { + #ifdef FD230_650 + long long size = SystemLogModel::GetInstance()->getFolderSize(TOTAL_RECORDING_SPACE_PATH); + if (size >= TOTAL_RECORDING_SPACE) + { + RecordingSpaceIsOut = true; + } + else + { + RecordingSpaceIsOut = false; + } + #endif + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingModel::CheckRecordingSpaceOut:%d", RecordingSpaceIsOut); + } + + bool RecordingModel::GetCheckRecordingSpaceOut(void) + { + return RecordingSpaceIsOut; + } + + void RecordingModel::SendCheckRecordingSpaceOutCmd(void) + { + do_custom_fileoperate_service_check_msg(CUSTOM_FILEOPERATE_MSG_TYPE_RECORDING_SPACE_READ, nullptr, 0); + } + + /* ----------------------------------- 定时器 ---------------------------------- */ + + /* + * @brief 显示录音时长 + */ + char *RecordingModel::DisplayRecordDuration() + { + recordDuration.erase(); + std::string hours; + std::string minute; + std::string seconds; + if (g_RecordingTimes >= NUM_TIME_DAY) + { + g_RecordingTimes = 0; + } + int hour = g_RecordingTimes / NUM_TIME_HOUR; + int min = (g_RecordingTimes % NUM_TIME_HOUR) / NUM_TIME_MIN; + int sec = (g_RecordingTimes % NUM_TIME_HOUR) % NUM_TIME_MIN; + if (hour >= 0 && hour < NUM_TEN) + { + hours = "0" + std::to_string(hour); + } + else + { + hours = std::to_string(hour); + } + if (min >= 0 && min < NUM_TEN) + { + minute = "0" + std::to_string(min); + } + else + { + minute = std::to_string(min); + } + if (sec >= 0 && sec < NUM_TEN) + { + seconds = "0" + std::to_string(sec); + } + else + { + seconds = std::to_string(sec); + } + +#if 1 + if (hour == 0) + { + recordTempDuration = minute + ":" + seconds; + } + else + { + recordTempDuration = hours + ":" + minute + ":" + seconds; + } + recordDuration = hours + ":" + minute + ":" + seconds; +#endif + + return (char *)recordDuration.c_str(); + } + + /* + * @brief 在这里添加定时器到期后的处理逻辑 + */ + static void Recording_TimerCallbackProc(int data) + { +#if 0 + g_RecordingTimes++; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "g_RecordingTimes:%d\n", g_RecordingTimes); + + if (RecordGoingView::GetInstance() == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[Recording_TimerCallbackProc] GetInstance is NULL"); + return; + } + + if (RecordGoingView::GetInstance()->GetRecordingDurationLabel() == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[Recording_TimerCallbackProc] GetInstance()->GetRecordingDurationLabel is NULL"); + return; + } + + if (RecordingModel::GetInstance()->DisplayRecordDuration() == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[Recording_TimerCallbackProc] DisplayRecordDuration is NULL"); + return; + } + + RecordGoingView::GetInstance()->GetRecordingDurationLabel()->SetText(RecordingModel::GetInstance()->DisplayRecordDuration()); +#endif + int g_TotalUsedTime = RecordingModel::GetInstance()->GetUsedRecordingTime(); // 已用时间 + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "g_RecordingTimes + g_TotalUsedTime = %d", g_RecordingTimes + g_TotalUsedTime); + if (RecordingModel::GetInstance()->CheckRecordingTimeOut(g_RecordingTimes + g_TotalUsedTime)) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Recording_TimerCallback g_TotalUsedSpace >= TOTAL_RECORDING_TIME"); + // 录取时长不足,停止录制并弹出警告 + if (RecordingPresenter::GetInstance()) + { + uapi_set_screen_on_api(); + if (true != OHOS::ConfigModel::GetInstance()->GetDnotdisturb() && (!uapi_sleep_mode_flag_get())) + { + // 震动提醒 + ui_api_vibrate_once_func(); + } + RecordingPresenter::GetInstance()->StopRecord(); // 停止录制 + RecordingPresenter::GetInstance()->showWarning(); // 显示警告 + } + } + g_RecordingTimes++; + } + + /* + * @brief 录音回调函数 + */ + static void Recording_TimerCallback(int data) + { + GraphicService::GetInstance()->PostGraphicEvent(std::bind(Recording_TimerCallbackProc, data)); + } + + /* + * @brief 开启定时器函数 + * @param interval 时间间隔,单位ms + */ + void RecordingModel::Recording_StartTimer(uint32_t interval) + { + /* -------------------------- 1.检查定时器是否已经存在,如果存在则返回 ------------------------- */ + if (g_timer != NULL) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingModel::Recording_StartTimer Timer already exists!!"); + return; + } + + /* --------------------------------- 2.创建定时器 -------------------------------- */ + g_timer = osTimerNew((osTimerFunc_t)Recording_TimerCallback, osTimerPeriodic, NULL, NULL); + // 检查定时器创建是否成功 + if (g_timer == NULL) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingModel::Recording_StartTimer Timer create failed!!"); + return; + } + + /* ----------------------------- 3.将毫秒转换为系统时钟节拍数 ---------------------------- */ + int tick = osMs2Tick(interval); + + /* --------------------------------- 4.启动定时器 -------------------------------- */ + osStatus_t ret = osTimerStart(g_timer, tick); + /* -------------------- 5.检查定时器启动是否成功,如果启动失败,删除定时器并置为 NULL -------------------- */ + if (ret != osOK) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ScanTimerCallback osTimerDelete failed, ret = %lx!!", ret); + if (g_timer != NULL) + { + ret = osTimerDelete(g_timer); + return; + } + g_timer = NULL; + } + return; + } + + /* + * @brief 停止定时器 + */ + void RecordingModel::Recording_StopTimer(void) + { + // 检查定时器是否存在 + if (g_timer != NULL) + { + osTimerStop(g_timer); + // 删除定时器并置为 NULL + osStatus_t ret = osTimerDelete(g_timer); + if (ret != osOK) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ScanTimerCallback osTimerDelete failed, ret = %lx!!", ret); + } + g_timer = NULL; + g_RecordingTimes = 0; + } + } + +} +#ifdef __cplusplus +#if __cplusplus +extern "C" +{ +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + void CheckRecordingSpaceOutC(void) + { + OHOS::RecordingModel::GetInstance()->CheckRecordingSpaceOut(); + } + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingNumLimitView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingNumLimitView.cpp new file mode 100644 index 000000000..e21e554f7 --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingNumLimitView.cpp @@ -0,0 +1,213 @@ +#include "record/include/RecordingNumLimitView.h" +#include "wearable_log.h" +#include "record/include/RecordingPresenter.h" +#include "UiConfig.h" +namespace OHOS +{ + + RecordingNumLimitView::RecordingNumLimitView() + { + } + + RecordingNumLimitView::~RecordingNumLimitView() + { + ClearAll(); + } + + void RecordingNumLimitView::ClearAll(void) + { + if (scrollView != nullptr) + { + scrollView->RemoveAll(); + if (title) + { + delete title; + title = nullptr; + } + if (image) + { + delete image; + image = nullptr; + } + if (note) + { + delete note; + note = nullptr; + } + if (goitlabel) + { + delete goitlabel; + goitlabel = nullptr; + } + if (goitbutton) + { + delete goitbutton; + goitbutton = nullptr; + } + delete scrollView; + scrollView = nullptr; + } + } + + UILabelExt *RecordingNumLimitView::CreateRecordingNumLimitLabel(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->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize); + return label; + } + + UIScrollView *RecordingNumLimitView::RecordingNumLimitViewInit(void) + { + if (scrollView == nullptr) + { + scrollView = new UIScrollView(); + if (scrollView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "scrollView new fail!"); + return nullptr; + } + scrollView->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + UIView::OnDragListener *draglistener = static_cast(RecordingPresenter::GetInstance()); + if (draglistener == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "draglistener can not be nullptr!"); + return nullptr; + } + scrollView->SetViewId(RECORDINGNUMLIMITVIEW); + scrollView->SetOnDragListener(draglistener); + scrollView->SetTouchable(true); + scrollView->SetDraggable(true); + /* -------------------------------------------------------------------------- */ + LabelConfig labelconfig = { + .left = 83, + .top = 50, + .width = 300, + .height = 35, + .fontSize = 30, + .lineHeigh = 35, + .textId = STR_RECORDER, + .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION, + }; + if (title == nullptr) + { + title = CreateRecordingNumLimitLabel(labelconfig); + if (title == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "title can not be nullptr!"); + return nullptr; + } + scrollView->Add(title); + } + /* -------------------------------------------------------------------------- */ + if (image == nullptr) + { + image = new UIImageView(); + if (image == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "image can not be nullptr!"); + return nullptr; + } + image->SetPosition(193, 120, 80, 80); + image->SetSrc(PNG_ATTENTION_IMAGE); + scrollView->Add(image); + } +/* -------------------------------------------------------------------------- */ +#if 0 + labelconfig = { + .left = 53, + .top = 222, + .width = 360, + .height = 70, + .fontSize = 30, + .lineHeigh = 35, + .textId = STR_VOICE_RECORDING_REMINDER_NOTE, // 录音数量不得超过30首,请删除已有录音 + .lineBreakMode = UILabel::LINE_BREAK_WRAP, + }; + if (note == nullptr) + { + note = CreateRecordingNumLimitLabel(labelconfig); + if (note == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "note can not be nullptr!"); + return nullptr; + } + scrollView->Add(note); + } +#else + if (note == nullptr) + { + note = new UILabelExt(); + if (note == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "note can not be nullptr!"); + return nullptr; + } + note->SetPosition(53, 222, 360, 70); // 位置大小 + note->SetStyle(STYLE_TEXT_FONT, 30); // 字体大小 + note->SetStyle(STYLE_LINE_HEIGHT, 35); // 字体行高 + note->SetTextId(STR_RECORD_MAX); + note->SetLineBreakMode(UILabel::LINE_BREAK_OSCILLATION); // 断行模式。 + note->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + note->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); + scrollView->Add(note); + } +#endif + /* -------------------------------------------------------------------------- */ + if (goitbutton == nullptr) + { + goitbutton = new UIButton(); + if (goitbutton == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "goitbutton can not be nullptr!"); + return nullptr; + } + goitbutton->SetPosition(93, 340, 280, 90); + goitbutton->SetViewId(RECORDINGNUMLIMITBUTTONVIEW); + goitbutton->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919); + goitbutton->SetStyle(STYLE_BACKGROUND_OPA, 0xff); + goitbutton->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff383838, UIButton::PRESSED); + UIView::OnClickListener *clicilistener = static_cast(RecordingPresenter::GetInstance()); + if (clicilistener == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "clicilistener can not be nullptr!"); + return nullptr; + } + goitbutton->SetOnClickListener(clicilistener); + scrollView->Add(goitbutton); + } + /* -------------------------------------------------------------------------- */ + int16_t y = goitbutton->GetY() + 28; + labelconfig = { + .left = 133, + .top = y, + .width = 200, + .height = 35, + .fontSize = 30, + .lineHeigh = 35, + .textId = STR_KONW, // 知道了 + .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION, + }; + if (goitlabel == nullptr) + { + goitlabel = CreateRecordingNumLimitLabel(labelconfig); + if (goitlabel == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "goitlabel can not be nullptr!"); + return nullptr; + } + scrollView->Add(goitlabel); + } + } + return scrollView; + } +} \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingPlayerView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingPlayerView.cpp new file mode 100644 index 000000000..e2be3b028 --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingPlayerView.cpp @@ -0,0 +1,476 @@ +#include "record/include/RecordingPlayerView.h" +#include "record/include/RecordingPresenter.h" +#include "record/include/RecordingModel.h" +#include "wearable_log.h" +#include "UiConfig.h" + +namespace OHOS +{ + + static RecordingPlayerView *g_pRecordPlayView{nullptr}; + + RecordingPlayerView::RecordingPlayerView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerView::RecordingPlayerView"); + g_pRecordPlayView = this; + } + + RecordingPlayerView::~RecordingPlayerView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerView::~RecordingPlayerView"); + ClearAll(); + g_pRecordPlayView = nullptr; + } + + RecordingPlayerView *RecordingPlayerView::GetInstance() + { + return g_pRecordPlayView; + } + + void RecordingPlayerView::ClearAll() + { + if (initViewStatus == true) + { + RecordingPlayerViewScrollView->RemoveAll(); + + delete RecordingPlayBackground; + RecordingPlayBackground = nullptr; + + delete RecordingFileName; + RecordingFileName = nullptr; + + delete RecordingTimeAndDuration; + RecordingTimeAndDuration = nullptr; + + delete PlayerProgressBarBackGround; + PlayerProgressBarBackGround = nullptr; + + delete PlayerProgressBar; + PlayerProgressBar = nullptr; + + delete RecordingPlayPauseButton; + RecordingPlayPauseButton = nullptr; + + delete RecordingPlayProveButton; + RecordingPlayProveButton = nullptr; + + delete RecordingPlayNextButton; + RecordingPlayNextButton = nullptr; + + delete RecordingPlayDeleteButton; + RecordingPlayDeleteButton = nullptr; + + delete RecordingPlayVolumeButton; + RecordingPlayVolumeButton = nullptr; + + delete buttonClick; + buttonClick = nullptr; + + delete RecordingPlayerViewScrollView; + RecordingPlayerViewScrollView = nullptr; + } + } + + // 设置标签 + UILabelExt *RecordingPlayerView::SetUpLabel(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->SetText(labelconfig.text); // 内容 + label->SetLineBreakMode(labelconfig.lineBreakMode); // 断行模式。 + label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, labelconfig.fontSize); + return label; + } + + // 设置按钮 + UIButton *RecordingPlayerView::SetTheButton(ButtonConfig &buttonconfig, UIView::OnClickListener *clickListener) + { + 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, 0xff000000); + button->SetStyle(STYLE_BACKGROUND_OPA, 0x00); + button->SetImageSrc(buttonconfig.ImageSrc, buttonconfig.ImageSrc); + button->SetImagePosition(20, 20); + button->SetStyle(STYLE_BORDER_RADIUS, 100); + button->SetStyleForState(STYLE_BACKGROUND_OPA, 0x00, UIButton::PRESSED); + button->SetOnClickListener(clickListener); + return button; + } + + // 亮屏时长视图“scrollView”初始化 + bool RecordingPlayerView::SetUpScrollView(void) + { + RecordingPlayerViewScrollView = new UIScrollView(); + if (RecordingPlayerViewScrollView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ScreenDurationView::RecordingPlayerViewScrollView new fail!"); + return false; + } + RecordingPlayerViewScrollView->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + UIView::OnDragListener *draglistener = static_cast(RecordingPresenter::GetInstance()); + if (draglistener == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ScreenDurationView::draglistener can not be nullptr!"); + return false; + } + RecordingPlayerViewScrollView->SetOnDragListener(draglistener); + RecordingPlayerViewScrollView->SetTouchable(true); + RecordingPlayerViewScrollView->SetDraggable(true); + return true; + } + + bool RecordingPlayerView::SetUpRecordingPlayerViewLabel(void) + { + LabelConfig labelconfig = { + .left = 83, + .top = 50, + .width = 300, + .height = 35, + .fontSize = 30, + .lineHeigh = 35, + .text = "", + .lineBreakMode = UILabel::LINE_BREAK_OSCILLATION, + }; + + RecordingFileName = SetUpLabel(labelconfig); + if (nullptr == RecordingFileName) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingPlayerView::RecordingFileName is nullptr!"); + return false; + } + + labelconfig.top = 102; + labelconfig.fontSize = 28; + labelconfig.lineHeigh = 33; + labelconfig.text = ""; + RecordingTimeAndDuration = SetUpLabel(labelconfig); + if (nullptr == RecordingTimeAndDuration) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingPlayerView::RecordingTimeAndDuration is nullptr!"); + return false; + } + RecordingTimeAndDuration->SetTextColor(Color::GetColorFromRGBA(0x99, 0x99, 0x99, 0xff)); + return true; + } + + /* + * @brief 背景设置 + */ + bool RecordingPlayerView::SetUpBackGround(void) + { + RecordingPlayBackground = new UIImageView(); + if (RecordingPlayBackground == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingPlayerView::RecordingPlayBackground is new fail!"); + return false; + } + RecordingPlayBackground->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + RecordingPlayBackground->SetSrc(PNG_RECORD_PLAY_BACKGROUND_IMAGE); + return true; + } + + // 播放进度条背景设置 + bool RecordingPlayerView::SetUpPlayerProgressBarBackGroud() + { + PlayerProgressBarBackGround = new UIImageView(); + if (PlayerProgressBarBackGround == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingPlayerView::PlayerProgressBarBackGround is new fail!"); + return false; + } + PlayerProgressBarBackGround->SetPosition(173, 173, 120, 120); + PlayerProgressBarBackGround->SetSrc(PNG_RECORD_PLAY_PROGRESS_BG_IMAGE); + PlayerProgressBarBackGround->SetStyle(STYLE_BORDER_RADIUS, 200); + return true; + } + + /* + * @brief 播放进度条设置 + */ + bool RecordingPlayerView::SetUpPlayerProgressBar(void) + { + PlayerProgressBar = new UICircleProgress(); + if (PlayerProgressBar == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingPlayerView::PlayerProgressBar is new fail!"); + return false; + } + PlayerProgressBar->SetPosition(168, 168, 130, 130); + PlayerProgressBar->SetViewId(RECORD_PLAY_PLAYERPROGRESSBAR); + PlayerProgressBar->SetStyle(STYLE_BACKGROUND_OPA, 0x00); + PlayerProgressBar->SetStyle(STYLE_BORDER_RADIUS, 100); + PlayerProgressBar->SetForegroundStyle(STYLE_BORDER_COLOR, 0xff000000); + PlayerProgressBar->SetForegroundStyle(STYLE_LINE_COLOR, 0xffffffff); + PlayerProgressBar->SetForegroundStyle(STYLE_LINE_WIDTH, 6); + PlayerProgressBar->SetBackgroundStyle(STYLE_BACKGROUND_COLOR, 0xff000000); + PlayerProgressBar->SetBackgroundStyle(STYLE_LINE_OPA, 0x00); + PlayerProgressBar->SetBackgroundStyle(STYLE_LINE_WIDTH, 0); + // PlayerProgressBar->SetCapType(CAP_ROUND); + PlayerProgressBar->SetCenterPosition(65, 65); + PlayerProgressBar->SetRadius(65); + PlayerProgressBar->SetStartAngle(0); + PlayerProgressBar->SetEndAngle(360); + PlayerProgressBar->SetValue(0); + + return true; + } + + /* + * @brief 播放和暂停按钮设置 + */ + bool RecordingPlayerView::SetUpPlayPauseButton(void) + { + RecordingPlayPauseButton = new UICheckBox(); + if (RecordingPlayPauseButton == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingPlayerView::RecordingPlayPauseButton is new fail!"); + return false; + } + RecordingPlayPauseButton->SetPosition(188, 188, 90, 90); + RecordingPlayPauseButton->SetViewId(RECORD_PLAY_PAUSE_CHECKBOX_VIEWID); + RecordingPlayPauseButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xffffffff); + RecordingPlayPauseButton->SetImages(PNG_UNIVERSAL_PAUSE_IMAGE, PNG_UNIVERSAL_PLAY_IMAGE); + RecordingPlayPauseButton->SetOnClickListener(buttonClick); + + return true; + } + + /* + * @brief 设置上一首按钮 + */ + bool RecordingPlayerView::SetUpProveButton(void) + { + ButtonConfig buttonconfig = + { + .x = 40, + .y = 193, + .w = 80, + .h = 80, + .ViewId = RECORD_PLAY_PROVE_BUTTON_VIEWID, + .ImageSrc = PNG_RECORD_PLAY_PROVE_IMAGE, + }; + RecordingPlayProveButton = SetTheButton(buttonconfig, buttonClick); + if (nullptr == RecordingPlayProveButton) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " RecordingPlayerView::RecordingPlayProveButton new fail!"); + return false; + } + return true; + } + + /* + * @brief 设置下一首按钮 + */ + bool RecordingPlayerView::SetUpNextButton(void) + { + + ButtonConfig buttonconfig = + { + .x = 346, + .y = 193, + .w = 80, + .h = 80, + .ViewId = RECORD_PLAY_NEXT_BUTTON_VIEWID, + .ImageSrc = PNG_RECORD_PLAY_NEXT_IMAGE, + }; + RecordingPlayNextButton = SetTheButton(buttonconfig, buttonClick); + if (nullptr == RecordingPlayNextButton) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " RecordingPlayerView::RecordingPlayNextButton new fail!"); + return false; + } + return true; + } + /* + * @brief 设置删除按钮 + */ + bool RecordingPlayerView::SetUpDeleteButton(void) + { + + ButtonConfig buttonconfig = + { + .x = 117, + .y = 326, + .w = 80, + .h = 80, + .ViewId = RECORD_PLAY_DELETE_BUTTON_VIEWID, + .ImageSrc = PNG_RECORD_PLAY_DELETE_IMAGE, + }; + RecordingPlayDeleteButton = SetTheButton(buttonconfig, buttonClick); + if (nullptr == RecordingPlayDeleteButton) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " RecordingPlayerView::RecordingPlayDeleteButton new fail!"); + return false; + } + return true; + } + + /* + * @brief 设置音量按钮 + */ + bool RecordingPlayerView::SetUpVolumeButton(void) + { + + ButtonConfig buttonconfig = + { + .x = 270, + .y = 326, + .w = 80, + .h = 80, + .ViewId = RECORD_PLAY_VOLUME_BUTTON_VIEWID, + .ImageSrc = PNG_RECORD_PLAY_VOLUME_IMAGE, + }; + RecordingPlayVolumeButton = SetTheButton(buttonconfig, buttonClick); + if (nullptr == RecordingPlayVolumeButton) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " RecordingPlayerView::RecordingPlayVolumeButton new fail!"); + return false; + } + return true; + } + + /* + * @brief 获取录音文件名标签 + */ + UILabelExt *RecordingPlayerView::GetRecordingFileNameLabel(void) + { + return RecordingFileName; + } + + /* + * @brief 获取录音时间和时长标签 + */ + UILabelExt *RecordingPlayerView::GetRecordingTimeAndDurationLabel(void) + { + return RecordingTimeAndDuration; + } + + /* + * @brief 获取播放器按钮 + */ + UICheckBox *RecordingPlayerView::GetPlayerButton(void) + { + return RecordingPlayPauseButton; + } + + /* + * @brief 设置播放器按钮状态 + */ + void RecordingPlayerView::SetPlayerButtonState(UICheckBox::UICheckBoxState state) + { + if (RecordingPlayPauseButton) + { + RecordingPlayPauseButton->SetState(state); + RecordingPlayPauseButton->Invalidate(); + } + } + + /* + * @brief 获取播放器状态 + */ + UICheckBox::UICheckBoxState RecordingPlayerView::GetPlayerButtonState(void) + { + if (RecordingPlayPauseButton == nullptr) + { + return UICheckBox::UICheckBoxState::UNSELECTED; + } + return RecordingPlayPauseButton->GetState(); + } + + /* + * @brief 获取录音播放进度条 + */ + UICircleProgress *RecordingPlayerView::GetPlayerProgressBar(void) + { + return PlayerProgressBar; + } + + /*设置录音播放进度条值*/ + void RecordingPlayerView::SetPlayerProgressBarValue(int value) + { + if (PlayerProgressBar) + { + PlayerProgressBar->SetValue(value); + PlayerProgressBar->Invalidate(); + } + } + + /* + * @brief 重置组件状态 + */ + void RecordingPlayerView::ResetComponentStatus(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[RecordingPlayerView] ResetComponentStatus"); + + RecordingModel *p_RecordingModel = RecordingModel::GetInstance(); + if (p_RecordingModel == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingModel::GetInstance fail!!"); + return; + } + + if (PlayerProgressBar != nullptr) + { + PlayerProgressBar->SetValue(0); // 0:进度0% + } + if (RecordingFileName != nullptr) + { + std::string name = p_RecordingModel->GetCurrentPlayRecordingName(); + RecordingFileName->SetText(p_RecordingModel->GetCurrentPlayRecordingName(name).c_str()); + } + if (RecordingTimeAndDuration != nullptr) + { + RecordingTimeAndDuration->SetText(RecordingModel::GetInstance()->Getyyyymmhhh_dateAndTotalRecordDuration().c_str()); + } + RecordingPlayerViewScrollView->Invalidate(); + // if (GetPlayerButton() != nullptr) + // { + // RecordingModel *p_RecordingModel = RecordingModel::GetInstance(); + // int32_t playerState = p_RecordingModel->GetRecordingPlayerState(); + // if (playerState != PlayerStates::PLAYER_STARTED) + // { + // SetPlayerButtonState(UICheckBox::UICheckBoxState::UNSELECTED); + // } + // } + } + + UIScrollView *RecordingPlayerView::RecordingPlayerViewInit() + { + buttonClick = static_cast(new RecordingPlayerViewOnClickListener()); + if (!SetUpScrollView() || !SetUpRecordingPlayerViewLabel() || !SetUpBackGround() || !SetUpPlayerProgressBarBackGroud() || !SetUpPlayerProgressBar() || + !SetUpPlayPauseButton() || !SetUpProveButton() || !SetUpNextButton() || !SetUpDeleteButton() || !SetUpVolumeButton()) + { + return nullptr; + } + /* ----------------------------------- Add ---------------------------------- */ + RecordingPlayerViewScrollView->Add(RecordingPlayBackground); + RecordingPlayerViewScrollView->Add(RecordingFileName); + RecordingPlayerViewScrollView->Add(RecordingTimeAndDuration); + RecordingPlayerViewScrollView->Add(PlayerProgressBarBackGround); + RecordingPlayerViewScrollView->Add(PlayerProgressBar); + RecordingPlayerViewScrollView->Add(RecordingPlayPauseButton); + RecordingPlayerViewScrollView->Add(RecordingPlayProveButton); + RecordingPlayerViewScrollView->Add(RecordingPlayNextButton); + RecordingPlayerViewScrollView->Add(RecordingPlayDeleteButton); + RecordingPlayerViewScrollView->Add(RecordingPlayVolumeButton); + /* -------------------------------------------------------------------------- */ + ResetComponentStatus(); // 设置“录音播放器”【录音文件名标签】的"文本内容"为被点击的"录音"的录音名 + /* -------------------------------------------------------------------------- */ + + initViewStatus = true; + return RecordingPlayerViewScrollView; + } + +} \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingPresenter.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingPresenter.cpp new file mode 100644 index 000000000..0475d24c2 --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingPresenter.cpp @@ -0,0 +1,895 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-03-30 09:14:38 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-12-18 14:33:46 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/record/src/RecordingPresenter.cpp + */ + +#include "AppViewIDs.h" +#include "components/ui_label_ext.h" +#include "ui_resource_string.h" +#include "NativeAbility.h" +#include "graphic_math.h" +#include "string.h" +#include "record/include/RecordingPresenter.h" +#include +#include "custom_utils.h" +#include "record/include/RecordingListitemView.h" +#include +#include +#include "record/include/RecordingModel.h" +#include +#include +#include "NativeRegisterManager.h" + +namespace OHOS +{ + REGIST_MENU_PRO(VIEW_RECORD, RecordingView, RecordingPresenter, + PNG_APPLIST_RECORD_IMAGE_BIG, PNG_APPLIST_RECORD_IMAGE,PNG_APPLIST_RECORD_IMAGE, "录音", STR_RECORD); + + + // 当前Presenter属性实例化的内存指针 + static RecordingPresenter *g_pRecordPresenter = nullptr; + + RecordingPresenter::RecordingPresenter() + { + p_RecordingModel = RecordingModel::GetInstance(); + g_pRecordPresenter = this; + } + + RecordingPresenter::~RecordingPresenter() + { + g_pRecordPresenter = nullptr; + } + + RecordingPresenter *RecordingPresenter::GetInstance() + { + + return g_pRecordPresenter; + } + + void RecordingPresenter::OnStart() + { + // 初始化录音信息 + p_RecordingModel->InitRecordingListItem(); + p_RecordingModel->AudioInit(); + p_RecordingModel->SendCheckRecordingSpaceOutCmd(); //进入录音视图后发送指令查看录音空间是否已满 + // ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON); + } + + void RecordingPresenter::OnPause(void) + { + Presenter::OnPause(); + } + + void RecordingPresenter::OnResume(void) + { + + Presenter::OnResume(); + } + + void RecordingPresenter::OnStop(void) + { + p_RecordingModel->ClearRecordingPlayer(); + StopRecord(); + // ScreenAlwaysOnCtr(CANCEL_SCREEN_ALWAYS_ON); + } + + bool RecordingPresenter::OnDrag(UIView &view, const DragEvent &event) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OnDrag"); + UNUSED(view); + UNUSED(event); + return true; + } + + bool RecordingPresenter::OnDragEnd(UIView &view, const DragEvent &event) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OnDragEnd"); + + RecordingView *p_RecordingView = RecordingView::GetInstance(); + if (p_RecordingView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingView GetInstance fail"); + return false; + } + + UIScrollView *scrollView = static_cast(&view); + if (scrollView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "scrollView is nullptr"); + return false; + } + + auto currentView = p_RecordingView->GetCurrentViewType(scrollView); + + switch (event.GetDragDirection()) + { + case DragEvent::DIRECTION_LEFT_TO_RIGHT: // 右滑退出 + switch (currentView) + { + case RECORDINGVIEW: + NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS); + break; + case RECORDINGPLAYERVIEW: + p_RecordingView->ChangeView(RECORDINGPLAYERVIEW, RECORDINGLISTVIEW); // 录音播放视图(subView)->录音列表视图(subView) + break; + case RECORDINGDELETEVIEW: + p_RecordingView->ChangeView(RECORDINGDELETEVIEW, RECORDINGPLAYERVIEW); // 录音删除视图(subView)->录音播放视图(subView) + break; + case RECORDINGVOLUMESETTINGVIEW: + p_RecordingView->ChangeView(RECORDINGVOLUMESETTINGVIEW, RECORDINGPLAYERVIEW); // 声音设置视图(subView)->录音播放视图(subView) + break; + case RECORDINGEXCELIMIT: + p_RecordingView->ChangeView(RECORDINGEXCELIMIT, RECORDINGVIEW); + break; + default: + break; + } + break; + case DragEvent::DIRECTION_BOTTOM_TO_TOP: + if (currentView == RECORDINGVIEW) + { + p_RecordingView->ChangeView(RECORDINGVIEW, RECORDINGLISTVIEW); + } + break; + default: + break; + } + + return true; + } + + /// @brief 解析时间 + /// @param numericDateTime "19700101000641"; // 输入的数字形式日期时间 + /// @param formattedDateTime + /// @return + int RecordingPresenter::convertNumericDateTime(const char *numericDateTime, char *formattedDateTime) + { + if (strlen(numericDateTime) != 14) + { + return 0; // 如果输入的数字长度不为14,则转换失败 + } + + struct tm timeinfo = {0}; + if (strptime(numericDateTime, "%Y%m%d%H%M%S", &timeinfo) == NULL) + { + return 0; // 解析失败 + } + + // 格式化输出为上午/下午几点几分几秒 + // strftime(formattedDateTime, 80, "%p %I点%M分%S秒", &timeinfo); + strftime(formattedDateTime, 80, "%p%H%M%S", &timeinfo); + return 1; // 转换成功 + } + +#ifdef __cplusplus + extern "C" + { +#endif + int32_t AudioCaptureSample(int32_t argc, const char *argv[]); + +#ifdef __cplusplus + }; +#endif + + /*开始录音*/ + void RecordingPresenter::StartRecord(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView StartRecord"); + char *args[6] = {0}; + const char *defaultArgs[6] = {"01", "mp3", "16000", "1", "16", nullptr}; // 默认参数数组 + for (int i = 0; i < 5; ++i) + { + args[i] = (char *)malloc(16); // 分配内存 + sprintf(args[i], "%s", defaultArgs[i]); // 设置默认参数值 + } + args[5] = (char *)malloc(100); // 分配内存 + /* -------------------------------------------------------------------------- */ + int num = p_RecordingModel->getMaxRecordingNumber(); + std::string recordfileNme; + // if (num < 9) + // { + // recordfileNme = "record_0" + std::to_string(num + 1); + // } + // else + // { + // recordfileNme = "record_" + std::to_string(num + 1); + // } + recordfileNme = std::to_string(num + 1); + p_RecordingModel->SetRecordFileName(recordfileNme); + sprintf(args[5], "%s%s.mp3", RecordingModel::GetInstance()->GetRecordDirectory(), recordfileNme.c_str()); + /* ---------------------------------- 开始录音 ---------------------------------- */ + uapi_save_runtime_log(RUNTIME_LOG_RECORD_START);//TOOD* + AudioCaptureSample(6, (const char **)args); + /* --------------------------------- 跳转到录音界面 -------------------------------- */ + view_->ChangeView(RECORDINGVIEW, RECORDGOINGVIEW); + p_RecordingModel->Recording_StartTimer(); + RecordGoingView::GetInstance()->GetRecordingDurationLabel()->SetText("00:00:00"); + /* ---------------------------------- 释放内存 ---------------------------------- */ + for (int i = 0; i < 6; ++i) + { + free(args[i]); + } + } + + // 停止录音 + void RecordingPresenter::StopRecord(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView StopRecord"); + int32_t argc = 1; + uint8_t *argv = (uint8_t *)"stop"; + AudioCaptureSample(argc, (const char **)&argv); + uapi_save_runtime_log(RUNTIME_LOG_RECORD_STOP);//TOOD* + /* ---------------------------------- 停止定时器 --------------------------------- */ + p_RecordingModel->Recording_StopTimer(); + /* --------------------------------- 录音数量加1 --------------------------------- */ + p_RecordingModel->SetRecordingListNum(p_RecordingModel->GetRecordingListNum() + 1); + /* --------------------------------- 设置录音信息 --------------------------------- */ + // int num = p_RecordingModel->GetRecordingListNum(); // 保存录音的下标 + std::string recordingFileName = p_RecordingModel->GetRecordFileName(); // 录音文件名 + // std::string yyymmhhh_date = RecordingModel::GetInstance()->Getyyyymmhhh_date(); // 保存录音年月日时间 + // std::string TotalRecordDuration = RecordingModel::recordTempDuration; // 录音的总时长 + // RecordingInfo info = {0}; + // strncpy_s(info.recordingFileName, 32, recordingFileName.c_str(), recordingFileName.length()); + // strncpy_s(info.recordingDuration, 16, TotalRecordDuration.c_str(), TotalRecordDuration.length()); + // strncpy_s(info.recordingTime, 16, yyymmhhh_date.c_str(), yyymmhhh_date.length()); + p_RecordingModel->RecordDataWriteToFile(recordingFileName.c_str()); + RecordingModel::GetInstance()->InitRecordingListItem(); + + p_RecordingModel->SendCheckRecordingSpaceOutCmd(); //录音完后发送指令查看录音空间是否已满 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingView StopRecord over!!"); + } + + //弹窗警告 + void RecordingPresenter::showWarning(void) + { + if(view_) + { + view_->ChangeView(RecordingModel::GetInstance()->GetCurView(), RECORDINGEXCELIMIT); + } + } + + bool RecordingPresenter::OnClick(UIView &view, const ClickEvent &event) + { + RecordingView *p_RecordingView = RecordingView::GetInstance(); + if (p_RecordingView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingView GetInstance fail"); + return false; + } + + if (strcmp(view.GetViewId(), RECORD_BUTTON) == 0) + { + int g_TotalUsedTime = RecordingModel::GetInstance()->GetUsedRecordingTime(); // 已用时间 + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "g_TotalUsedTime:%d", g_TotalUsedTime); + if (p_RecordingModel->CheckRecordingTimeOut(g_TotalUsedTime) || p_RecordingModel->GetRecordingListNum() >= MAX_RECORDING_NUM || + p_RecordingModel->GetCheckRecordingSpaceOut()) + { + view_->ChangeView(RECORDINGVIEW, RECORDINGEXCELIMIT); + return true; + } + StartRecord(); + return true; + } + else if (strcmp(view.GetViewId(), RECORD_GOING_BUTTON_VIEWID) == 0) + { + StopRecord(); + view_->ChangeView(RECORDGOINGVIEW, RECORDINGVIEW); + return true; + } + else if (strcmp(view.GetViewId(), RECORD_DELETE_ON_BUTTON_VIEWID) == 0) // 若点击的是录音删除按钮 + { + int index = p_RecordingModel->GetClickRecordingIndex(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "index = %d", index); + // std::string delete_path = RecordingModel::GetInstance()->GetRecordDirectory(); + // std::string delete_filename = p_RecordingModel->GetFileNames()[index] + ".mp3"; + // std::string fileName = delete_path + delete_filename; + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "index = %d ", index); + // uapi_delete_files(fileName.c_str());//删除录音文件 + p_RecordingModel->UpdateRecordingInfo(); + + p_RecordingView->ChangeView(RECORDINGDELETEVIEW, RECORDINGLISTVIEW); + return true; + } + else if (strcmp(view.GetViewId(), RECORD_DELETE_OFF_BUTTON_VIEWID) == 0) + { + p_RecordingView->ChangeView(RECORDINGDELETEVIEW, RECORDINGPLAYERVIEW); + return true; + } + else if (strcmp(view.GetViewId(), RECORDINGNUMLIMITBUTTONVIEW) == 0) + { + p_RecordingView->ChangeView(RECORDINGEXCELIMIT, RECORDINGVIEW); + return true; + } + return true; + } + + bool RecordingPresenter::OnKeyAct(UIView &view, const KeyEvent &event) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPresenter::OnKeyAct"); + uint16 keyID = event.GetKeyId(); + uint16_t keyState = event.GetState(); + // 如果是power键就返回上一级 + if (keyID == static_cast(ZliteKeyCode::ZLITE_KEY_POWER) && keyState == 1 && uapi_get_screen_state() == 0) + { + NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS); + } + return true; + } + + void RecordingPresenter::Notify() + { + //如果是在正在录音视图且正在录音视图为可见 + if(view_->GetRecordingViewScrollView(RECORDGOINGVIEW) && view_->GetRecordingViewScrollView(RECORDGOINGVIEW)->IsVisible()) + { + if(RecordGoingView::GetInstance()->GetRecordingDurationLabel()) + { + RecordGoingView::GetInstance()->GetRecordingDurationLabel()->SetText(RecordingModel::GetInstance()->DisplayRecordDuration()); + } + } + } + + + void RecordingPresenter::SetCircleProgress() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPresenter::SetCircleProgress"); + RecordingPlayerView *p_RecordingPlayerView = RecordingPlayerView::GetInstance(); + if (p_RecordingPlayerView == nullptr) + { + return; + } + UICircleProgress *playbackProgress = p_RecordingPlayerView->GetPlayerProgressBar(); + if (playbackProgress == nullptr) + { + return; + } + int32_t playerState; + playerState = p_RecordingModel->GetRecordingPlayerState(); + state_ = p_RecordingPlayerView->GetPlayerButtonState(); + if ((playerState != PLAYER_STARTED) && (state_ == UICheckBox::UICheckBoxState::SELECTED)) + { + p_RecordingPlayerView->SetPlayerButtonState(UICheckBox::UICheckBoxState::UNSELECTED); + } + else if ((playerState == PLAYER_STARTED) && (state_ == UICheckBox::UICheckBoxState::UNSELECTED)) + { + p_RecordingPlayerView->SetPlayerButtonState(UICheckBox::UICheckBoxState::SELECTED); + } + if (state_ == UICheckBox::UICheckBoxState::SELECTED) + { + p_RecordingModel->GetPlayerCtr()->GetCurrentTime(playerCurrentTime_); + p_RecordingModel->GetDuration(playerMusicDuration_); + if (playerMusicDuration_ != 0) + { + playerProgressValue_ = (playerCurrentTime_ * 100) / playerMusicDuration_; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "playerProgressValue_ %lld", playerProgressValue_); + } + else + { + playerProgressValue_ = 100; // 100: max progress value + } + p_RecordingModel->SetCircleProgress(playerProgressValue_); + p_RecordingPlayerView->SetPlayerProgressBarValue(playerProgressValue_); + } + } + + void RecordingPresenter::UpdateRecordProcess() + { + if (view_ == nullptr) + { + return; + } + if (view_->GetRecordingViewScrollView(RECORDINGPLAYERVIEW)) + { + if (view_->GetRecordingViewScrollView(RECORDINGPLAYERVIEW)->IsVisible()) + { + SetCircleProgress(); + } + } + } + // 录音列表点击监听 + bool RecordListViewListener::OnClick(UIView &view, const ClickEvent &event) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordListViewListener::OnClick"); + UNUSED(event); + RecordingListitemView *p_RecordingListitemView = static_cast(&view); + int index = p_RecordingListitemView->GetRecordingListIndex(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordListViewListener::OnClick index:%d", index); + if (index >= RecordingModel::GetInstance()->GetRecordingListNum()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordListViewListener::OnClick is no index"); + return false; + } + /* -------------------------------- 保存被点击录音下标 ------------------------------- */ + RecordingModel *p_RecordingModel = RecordingModel::GetInstance(); + if (p_RecordingModel == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingModel GetInstance fail"); + return false; + } + p_RecordingModel->SetClickRecordingIndex(index); // 标记当前要播放录音的index_ + RecordingView *p_RecordingView = RecordingView::GetInstance(); + if (p_RecordingView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingView GetInstance fail"); + return false; + } + p_RecordingView->ChangeView(RECORDINGLISTVIEW, RECORDINGPLAYERVIEW); // 切换到录音播放界面 + RecordingPlayerView *p_RecordingPlayerView = RecordingPlayerView::GetInstance(); + if (p_RecordingPlayerView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingPlayerView GetInstance fail"); + return false; + } + p_RecordingPlayerView->ResetComponentStatus(); + /* ------------------------ 播放录音 ------------------------ */ + if (p_RecordingModel->RecordingListOnClickPlay() != OHOS_SUCCESS) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "p_RecordingModel->RecordingListOnClickPlay fail!!"); + return false; + } + + return true; + } + + // 录音列表拖拽中监听 + bool RecordListViewListener::OnDrag(UIView &view, const DragEvent &event) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordListViewListener::OnDrag"); + UNUSED(view); + UNUSED(event); + // if ((event.GetDeltaY() > X_DRAG_OFFSET) && (event.GetDeltaY() > (DOUBLES * MATH_ABS(event.GetDeltaX())))) // 如果滑动的为直线 + // { + // RecordListViewListener::X_DRAG_FLAG = true; + // } + return true; + } + + // 录音列表拖拽结束监听 + bool RecordListViewListener::OnDragEnd(UIView &view, const DragEvent &event) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordListViewListener::OnDragEnd"); + std::string viewId = view.GetViewId(); + if (event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) + { + if (RecordingView::GetInstance() != nullptr && viewId == RECORDLISTSCROLLVIEW) + { + RecordingView::GetInstance()->ChangeView(RECORDINGLISTVIEW, RECORDINGVIEW); + // RecordListViewListener::X_DRAG_FLAG = false; + } + } + return true; + } + + void RecordingPlayerViewOnClickListener::PlayerButtonOnClick(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerViewOnClickListener PlayerButtonOnClick,%d",__LINE__); + + RecordingPlayerView *p_RecordingPlayerView = RecordingPlayerView::GetInstance(); + if (p_RecordingPlayerView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingPlayerView GetInstance fail"); + return; + } + + RecordingModel *p_RecordingModel = RecordingModel::GetInstance(); + if (p_RecordingModel == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "p_RecordingModel GetInstance fail"); + return; + } + + int ret; + uint8_t state = UICheckBox::UICheckBoxState::MAX_STATUS_NUM; + int32_t playerState; + + state = p_RecordingPlayerView->GetPlayerButtonState(); + playerState = p_RecordingModel->GetRecordingPlayerState(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "buttonState = %d playerState = %d", state, playerState); + + if (state == UICheckBox::UICheckBoxState::SELECTED) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "state == SELECTED"); + + if (playerState == PlayerStates::PLAYER_PAUSED) + { + ret = p_RecordingModel->GetPlayerCtr()->Play(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Play, ret:%d", ret); + } + else + { + ret = p_RecordingModel->RecordingPlayerStat(); // 本地播放 + if (ret != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PlayerStat err, ret:%d", ret); + } + } + } + else + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "state == UNSELECTED"); + ret = p_RecordingModel->GetPlayerCtr()->Pause(); // 本地暂停 + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Pause, ret:%d", ret); + } + } + + bool RecordingPlayerViewOnClickListener::OnClick(UIView &view, const ClickEvent &event) + { + RecordingView *p_RecordingView = RecordingView::GetInstance(); + if (p_RecordingView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingView GetInstance fail"); + return false; + } + + RecordingPlayerView *p_RecordingPlayerView = RecordingPlayerView::GetInstance(); + if (p_RecordingPlayerView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingPlayerView GetInstance fail"); + return false; + } + + RecordingModel *p_RecordingModel = RecordingModel::GetInstance(); + if (p_RecordingModel == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "p_RecordingModel GetInstance fail"); + return false; + } + + if (strcmp(view.GetViewId(), RECORD_PLAY_PAUSE_CHECKBOX_VIEWID) == 0) // 播放和暂停按钮被点击 + { + PlayerButtonOnClick(); + } + else if (strcmp(view.GetViewId(), RECORD_PLAY_PROVE_BUTTON_VIEWID) == 0) // 上一首按钮被点击 + { + p_RecordingModel->PreviousPlayout(); + p_RecordingPlayerView->ResetComponentStatus(); + } + else if (strcmp(view.GetViewId(), RECORD_PLAY_NEXT_BUTTON_VIEWID) == 0) // 下一首按钮被点击 + { + p_RecordingModel->NextPlayout(); + p_RecordingPlayerView->ResetComponentStatus(); + } + else if (strcmp(view.GetViewId(), RECORD_PLAY_DELETE_BUTTON_VIEWID) == 0) // 删除按钮被点击 + { + p_RecordingView->ChangeView(RECORDINGPLAYERVIEW, RECORDINGDELETEVIEW); + } + else if (strcmp(view.GetViewId(), RECORD_PLAY_VOLUME_BUTTON_VIEWID) == 0) // 音量按钮被点击 + { + p_RecordingView->ChangeView(RECORDINGPLAYERVIEW, RECORDINGVOLUMESETTINGVIEW); + } + return true; + } + + /* -------------------- RecordingPlayerInterruptListener -------------------- */ + /* + * @brief 音频中断类的构造函数 + */ + RecordingPlayerInterruptListener::RecordingPlayerInterruptListener() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerInterruptListener::RecordingPlayerInterruptListener"); + } + + RecordingPlayerInterruptListener::~RecordingPlayerInterruptListener() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerInterruptListener::~RecordingPlayerInterruptListener"); + } + /* + * 函数的调用通常发生在音频播放器或者任何使用音频资源的应用程序遇到外部中断事件时。 + * 这些中断事件可能包括电话来电、音乐播放器之间的音频焦点切换、系统声音(如闹钟)的播放,或者其他任何需要暂停当前活动以响应的情况。 + * @brief 处理录音播放器中断的方法,可能会根据传入的参数进行不同的操作。 + * @param type 中断的类型 + * @param hint 处理中断的额外提示 + */ + void RecordingPlayerInterruptListener::OnInterrupt(int32_t type, int32_t hint) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerInterruptListener::OnInterrupt"); + if (type == INTERRUPT_TYPE_BEGIN && hint == INTERRUPT_HINT_PAUSE) // 这表明当某个中断事件开始时,如果接收到暂停的提示,应当暂停播放器的播放。 + { + PausePlayer(); + } + + if (type == INTERRUPT_TYPE_END && hint == INTERRUPT_HINT_RESUME) // 这意味着一旦中断事件结束,并且有指示可以恢复播放的提示,就尝试恢复播放器的播放。 + { + ResumePlayer(); + } + + if (hint == INTERRUPT_HINT_STOP) // 只要提示为INTERRUPT_HINT_STOP,首先调用ResetFlag方法重置相关标志。 + { + ResetFlag(); + if (type == INTERRUPT_TYPE_BEGIN) // 这表示如果在中断开始时接收到停止的提示,应当停止播放器的播放并标记该事件。 + { + isBeginStopped_ = true; + StopPlayer(); + } + else if (type == INTERRUPT_TYPE_END) // 记录中断结束时播放器已被停止 + { + isEndStopped_ = true; + } + } + } + + /* + * @brief 获取与该监听器相关联的播放器。 + */ + std::shared_ptr RecordingPlayerInterruptListener::GetPlayer() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerInterruptListener::GetPlayer"); + + return player_; + } + + /* + * @brief 设置录音播放器的所有者。 + */ + void RecordingPlayerInterruptListener::SetOwner(std::shared_ptr player) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerInterruptListener::SetOwner"); + + player_ = player; + } + + /* + * @brief 设置播放器是否处于暂停状态 + */ + void RecordingPlayerInterruptListener::SetPaused(bool value) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerInterruptListener::SetPaused"); + + isPaused_ = value; + } + + /* + * @brief 设置播放器是否已恢复播放状态。 + */ + void RecordingPlayerInterruptListener::SetResumed(bool value) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerInterruptListener::SetResumed"); + isResumed_ = value; + } + + /* + * @brief 重置标志位 + */ + void RecordingPlayerInterruptListener::ResetFlag(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerInterruptListener::RestFlag"); + + isPaused_ = false; + isDelayed_ = false; + isResumed_ = false; + isBeginStopped_ = false; + isEndStopped_ = false; + } + + /* + * @brief 返回播放器是否处于暂停状态的布尔值 + */ + bool RecordingPlayerInterruptListener::IsPaused() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerInterruptListener::IsPaused"); + + return isPaused_; + } + + /* + * @brief 返回播放器是否处于延迟状态的布尔值。 + */ + bool RecordingPlayerInterruptListener::IsDelayed() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerInterruptListener::IsDelayed"); + + return isDelayed_; + } + + /* + * @brief 返回播放器是否已恢复播放状态的布尔值 + */ + bool RecordingPlayerInterruptListener::IsResumed() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerInterruptListener::IsDelayed"); + + return isResumed_; + } + + /* + * @brief 返回播放器是否已开始停止的布尔值。 + */ + bool RecordingPlayerInterruptListener::IsBeginStopped() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerInterruptListener::IsBeginStopped"); + + return isBeginStopped_; + } + + /* + * @brief 返回播放器是否已结束停止的布尔值。 + */ + bool RecordingPlayerInterruptListener::IsEndStopped() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerInterruptListener::IsEndStopped"); + + return isEndStopped_; + } + + static void PlayerPostGraphicEvent(void (*fun)(void)) + { + GraphicService::GetInstance()->PostGraphicEvent(*fun); + } + + static void Pause(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[RecordingPlayerInterruptListener::PausePlayer] start"); + int32_t state; + int32_t ret; + std::shared_ptr PlayerIntrptListener = + OHOS::RecordingModel::GetInstance()->GetRecordingPlayerIntrptListener(); + if (PlayerIntrptListener == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[RecordingPlayerInterruptListener] PlayerIntrptListener is null"); + return; + } + + std::shared_ptr player = PlayerIntrptListener->GetPlayer(); + if (player.get() == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[RecordingPlayerInterruptListener::PausePlayer] player is nullptr"); + return; + } + + RecordingPlayerView *p_RecordingPlayerView = RecordingPlayerView::GetInstance(); + + player->GetPlayerState(state); + if (state == PLAYER_STARTED) + { + ret = player->Pause(); + if (ret == 0) + { + if (p_RecordingPlayerView == nullptr) + { + RecordingModel::GetInstance()->SetRecordingPlayButtonState(false); + } + else + { + p_RecordingPlayerView->SetPlayerButtonState(UICheckBox::UICheckBoxState::UNSELECTED); + } + PlayerIntrptListener->ResetFlag(); + PlayerIntrptListener->SetPaused(true); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[RecordingPlayerInterruptListener::PausePlayer]"); + } + } + } + + static void Resume(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[RecordingPlayerInterruptListener::ResumePlayer] start"); + int32_t state; + int32_t ret; + /* ----------------------------- 1.获取播放器中断监听器实例 ----------------------------- */ + std::shared_ptr PlayerIntrptListener = + OHOS::RecordingModel::GetInstance()->GetRecordingPlayerIntrptListener(); + if (PlayerIntrptListener == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[RecordingPlayerInterruptListener] PlayerIntrptListener is null"); + return; + } + /* ------------------------------- 2.获取播放器实例 ------------------------------- */ + std::shared_ptr player = PlayerIntrptListener->GetPlayer(); + if (player.get() == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[RecordingPlayerInterruptListener::ResumePlayer] player is nullptr"); + return; + } + + /* ------------------------------- 3.获取播放器视图实例 ------------------------------ */ + RecordingPlayerView *p_RecordingPlayerView = RecordingPlayerView::GetInstance(); + /* --------------------------------- 4.检查播放器状态 -------------------------------- */ + player->GetPlayerState(state); + if (state == PLAYER_PAUSED && PlayerIntrptListener->IsPaused() == true) + { + /* -------------------------------- 5.尝试恢复播放 -------------------------------- */ + ret = player->Play(); + if (ret == 0) + { + if (p_RecordingPlayerView == nullptr) + { + RecordingModel::GetInstance()->SetRecordingPlayButtonState(true); + } + else + { + p_RecordingPlayerView->SetPlayerButtonState(UICheckBox::UICheckBoxState::SELECTED); + } + /* ------------------------------- 6.重置中断监听器状态 ------------------------------ */ + PlayerIntrptListener->ResetFlag(); + PlayerIntrptListener->SetResumed(true); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[RecordingPlayerInterruptListener::ResumePlayer]"); + } + } + } + + static void Stop(void) + { + RecordingModel::GetInstance()->RecordingPlayerStop(); + RecordingModel::GetInstance()->ClearActivateAudioInterrupt(); + } + + /* + * @brief 暂停播放器 + */ + void RecordingPlayerInterruptListener::PausePlayer(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerInterruptListener::PausePlayer"); + + PlayerPostGraphicEvent(Pause); + } + + /* + * @brief 恢复播放器。 + */ + void RecordingPlayerInterruptListener::ResumePlayer(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerInterruptListener::ResumePlayer"); + + PlayerPostGraphicEvent(Resume); + } + + /* + * @brief 停止播放器 + */ + void RecordingPlayerInterruptListener::StopPlayer(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerInterruptListener::StopPlayer"); + + PlayerPostGraphicEvent(Stop); + } + /* ---------------------------------- 播放器回调 --------------------------------- */ + RecordingPlayerCallbackImpl::RecordingPlayerCallbackImpl() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerCallbackImpl::RecordingPlayerCallbackImpl"); + } + + RecordingPlayerCallbackImpl::~RecordingPlayerCallbackImpl() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerCallbackImpl::~RecordingPlayerCallbackImpl"); + } + + void RecordingPlayerCallbackImpl::OnPlaybackComplete() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerCallbackImpl::OnPlaybackComplete"); + /* --------------------------- 处实现代码用于处理文件播放完成的事件 --------------------------- */ + /* ----------------------- 用户在回调函数中不能有阻塞操作,也不能调用播放器接口 ----------------------- */ + // 此处实现代码用于处理文件播放完成的事件 + RecordingPlayerView *p_RecordingPlayerView = RecordingPlayerView::GetInstance(); + if (p_RecordingPlayerView != nullptr) + { + if (p_RecordingPlayerView->GetPlayerProgressBar() != nullptr) + { + p_RecordingPlayerView->GetPlayerProgressBar()->SetValue(100); // 100:进度100% + p_RecordingPlayerView->SetPlayerButtonState(UICheckBox::UICheckBoxState::UNSELECTED); + p_RecordingPlayerView->GetPlayerProgressBar()->Invalidate(); + } + } + usleep(20000); + GraphicService::GetInstance()->PostGraphicEvent( + std::bind(&OHOS::RecordingModel::RecordingPlayerReset, OHOS::RecordingModel::GetInstance())); + } + + void RecordingPlayerCallbackImpl::OnError(int32_t errorType, int32_t errorCode) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerCallbackImpl::OnError"); + /* ------------------------------ 此处实现代码用于处理错误事件 ------------------------------ */ + } + + void RecordingPlayerCallbackImpl::OnInfo(int type, int extra) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerCallbackImpl::OnInfo"); + /* ------------------------------- 此处实现代码用于处理普通事件 ------------------------------ */ + } + + void RecordingPlayerCallbackImpl::OnRewindToComplete() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingPlayerCallbackImpl::OnRewindToComplete"); + /* ---------------------------- 此处实现代码用于处理进度控制完成的事件 ---------------------------- */ + } +} \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingView.cpp new file mode 100644 index 000000000..6e218152a --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingView.cpp @@ -0,0 +1,460 @@ +#include "record/include/RecordingView.h" +#include "record/include/RecordingPresenter.h" +#include "UiConfig.h" +#include "wearable_log.h" +#include "../include/RecordingModel.h" +namespace OHOS +{ + static RecordingView *g_pRecordView{nullptr}; + RecordingView::RecordingView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView::RecordingView"); + g_pRecordView = this; + } + RecordingView::~RecordingView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView::~RecordingView"); + ClearAll(); + g_pRecordView = nullptr; + } + void RecordingView::ClearAll(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView::~RecordingView"); + if (RecordingViewScrollView[RECORDINGVIEW] != nullptr) + { + RecordingViewScrollView[RECORDINGVIEW]->RemoveAll(); + + if (RecordingViewTitleLabel != nullptr) + { + delete RecordingViewTitleLabel; + RecordingViewTitleLabel = nullptr; + } + if (RecordingViewButton != nullptr) + { + delete RecordingViewButton; + RecordingViewButton = nullptr; + } + if (AttentionLabel != nullptr) + { + delete AttentionLabel; + AttentionLabel = nullptr; + } + if (RECORD1_Image != nullptr) + { + delete RECORD1_Image; + RECORD1_Image = nullptr; + } + if (pullUp_Image != nullptr) + { + delete pullUp_Image; + pullUp_Image = nullptr; + } + delete RecordingViewScrollView[RECORDINGVIEW]; + RecordingViewScrollView[RECORDINGVIEW] = nullptr; + } + if (p_RecordListView != nullptr) + { + delete p_RecordListView; + p_RecordListView = nullptr; + } + if (p_RecordGoingView != nullptr) + { + delete p_RecordGoingView; + p_RecordGoingView = nullptr; + } + if (p_RecordingPlayerView != nullptr) + { + delete p_RecordingPlayerView; + p_RecordingPlayerView = nullptr; + } + if (p_RecordDeleteView != nullptr) + { + delete p_RecordDeleteView; + p_RecordDeleteView = nullptr; + } + if (p_RecordingVolumeSettingView != nullptr) + { + delete p_RecordingVolumeSettingView; + p_RecordingVolumeSettingView = nullptr; + } + if (p_RecordingNumLimitView != nullptr) + { + delete p_RecordingNumLimitView; + p_RecordingNumLimitView = nullptr; + } + for (int i = RECORDINGVIEW; i < MAX_RECORDINGVIEWID; i++) + { + RecordingViewScrollView[i] = nullptr; + } + } + + RecordingView *RecordingView::GetInstance() + { + return g_pRecordView; + } + + int RecordingView::GetCurrentViewType(UIScrollView *view) + { + for (int i = 0; i < MAX_RECORDINGVIEWID; ++i) + { + if (view == RecordingViewScrollView[i]) + { + return i; + } + } + return MAX_RECORDINGVIEWID; + } + + UIScrollView *RecordingView::GetRecordingViewScrollView(int index) + { + return RecordingViewScrollView[index]; + } + + /* + * @brief 切换到“录音”视图 + */ + bool RecordingView::ChangeRecordingView(int16_t thisView) + { + if (RecordingViewScrollView[thisView] == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingView::ChangeRecordingView"); + AddViewToRootContainer(RecordingViewScrollView[thisView]); + } + return true; + } + + /* + * @brief 切换到录音列表视图 + */ + bool RecordingView::ChangeRecordListView(int16_t thisView) + { + if (RecordingViewScrollView[thisView] == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView::ChangeRecordListView"); + p_RecordListView = new RecordListView(); + if (p_RecordListView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingView:: new scrollView[%d] fail", thisView); + return false; + } + RecordingViewScrollView[thisView] = p_RecordListView->RecordListViewInit(); + AddViewToRootContainer(RecordingViewScrollView[thisView]); + } + else + { + RecordingModel::GetInstance()->ClearRecordingPlayer(); + } + if (p_RecordListView) + { + p_RecordListView->RefreshRecordingListData(); + } + return true; + } + + /* + * @brief 切换到“正在录音”视图 + */ + bool RecordingView::ChangeRecordGoingView(int16_t thisView) + { + if (RecordingViewScrollView[thisView] == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView::ChangeRecordGoingView"); + p_RecordGoingView = new RecordGoingView(); + if (p_RecordGoingView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingView:: new scrollView[%d] fail", thisView); + return false; + } + RecordingViewScrollView[thisView] = p_RecordGoingView->RecordGoingViewInit(); + AddViewToRootContainer(RecordingViewScrollView[thisView]); + } + return true; + } + + /* + * @brief 切换到“录音播放”视图 + */ + bool RecordingView::ChangeRecordingPlayerView(int16_t thisView) + { + if (RecordingViewScrollView[thisView] == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView::ChangeRecordingPlayerView"); + p_RecordingPlayerView = new RecordingPlayerView(); + if (p_RecordingPlayerView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingView:: new scrollView[%d] fail", thisView); + return false; + } + RecordingViewScrollView[thisView] = p_RecordingPlayerView->RecordingPlayerViewInit(); + AddViewToRootContainer(RecordingViewScrollView[thisView]); + } + return true; + } + + /* + * @brief 切换到“录音删除”视图 + */ + bool RecordingView::ChangeRecordDeleteView(int16_t thisView) + { + if (RecordingViewScrollView[thisView] == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView::ChangeRecordDeleteView"); + p_RecordDeleteView = new RecordDeleteView(); + if (p_RecordDeleteView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingView:: new scrollView[%d] fail", thisView); + return false; + } + RecordingViewScrollView[thisView] = p_RecordDeleteView->RecordDeleteViewInit(); + AddViewToRootContainer(RecordingViewScrollView[thisView]); + } + std::string name = RecordingModel::GetInstance()->GetCurrentPlayRecordingName(); + p_RecordDeleteView->SetRecordDeleteName(name.c_str()); + return true; + } + + /* + * @brief 切换到“声音设置”视图 + */ + bool RecordingView::ChangeRecordVolumeSettingView(int16_t thisView) // 切换到“声音设置”视图 + { + if (RecordingViewScrollView[thisView] == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView::ChangeRecordVolumeSettingView"); + p_RecordingVolumeSettingView = new RecordingVolumeSettingView(); + if (p_RecordingVolumeSettingView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingView:: new scrollView[%d] fail", thisView); + return false; + } + RecordingViewScrollView[thisView] = p_RecordingVolumeSettingView->RecordingVolumeSettingViewInit(); + AddViewToRootContainer(RecordingViewScrollView[thisView]); + } + return true; + } + + // 切换到“录音超出限制”视图 + bool RecordingView::ChangeRecordNumLimitView(int16_t thisView) + { + if (RecordingViewScrollView[thisView] == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView::ChangeRecordNumLimitView"); + p_RecordingNumLimitView = new RecordingNumLimitView(); + if (p_RecordingNumLimitView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingView:: new scrollView[%d] fail", thisView); + return false; + } + RecordingViewScrollView[thisView] = p_RecordingNumLimitView->RecordingNumLimitViewInit(); + AddViewToRootContainer(RecordingViewScrollView[thisView]); + } + return true; + } + + // 1.RecordingViewMapper:结构体定义了一个将视图ID映射到特定成员函数指针的映射表。 + struct RecordingViewMapper + { + const int16_t viewId; + bool (RecordingView::*func)(int16_t thisView); + }; + + // 2.ViewMapper[] 是一个静态的视图映射数组,将视图ID与RecordingViewMapper类中的特定成员函数指针进行了绑定。 + static const RecordingViewMapper ViewMapper[] = { + {RECORDINGVIEW, &RecordingView::ChangeRecordingView}, + {RECORDINGLISTVIEW, &RecordingView::ChangeRecordListView}, + {RECORDGOINGVIEW, &RecordingView::ChangeRecordGoingView}, + {RECORDINGPLAYERVIEW, &RecordingView::ChangeRecordingPlayerView}, + {RECORDINGDELETEVIEW, &RecordingView::ChangeRecordDeleteView}, + {RECORDINGVOLUMESETTINGVIEW, &RecordingView::ChangeRecordVolumeSettingView}, + {RECORDINGEXCELIMIT, &RecordingView::ChangeRecordNumLimitView}, + }; + + // 3.根据传入的interface参数执行相应视图ID关联的成员函数。 + bool RecordingView::ClickFunc(int16_t interface) + { + int funcSize = sizeof(ViewMapper) / sizeof(ViewMapper[0]); + for (int i = 0; i < funcSize; i++) + { + if (interface == ViewMapper[i].viewId) + { + bool jug = (this->*(ViewMapper[i].func))(interface); + if (jug == false) + { + return false; + } + return true; + } + } + return false; + } + + // 4.切换视图 + void RecordingView::ChangeView(int16_t hideView, int16_t showView) + { + if (hideView > MAX_RECORDINGVIEWID) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingView:: RecordingViewID Overstep ones bounds"); + return; + } + RecordingViewScrollView[hideView]->SetVisible(false); + ClickFunc(showView); + RecordingViewScrollView[showView]->SetVisible(true); + RecordingModel::GetInstance()->SetCurView(showView); + Draw(); + } + + UIButton *RecordingView::SetTheButton(ButtonConfig &buttonconfig, UIView::OnClickListener *clickListener) + { + UIButton *button = new UIButton(); + if (button == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " SetTheButton: button new fail!"); + return nullptr; + } + button->SetPosition(buttonconfig.x, buttonconfig.y, buttonconfig.w, buttonconfig.h); + button->SetViewId(buttonconfig.ViewId); + button->SetStyle(STYLE_BACKGROUND_COLOR, 0xffff5a36); + button->SetStyle(STYLE_BORDER_RADIUS, 100); + button->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xffff5a36, UIButton::PRESSED); + button->SetOnClickListener(clickListener); + return button; + } + + bool RecordingView::RecordingScrollViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView::RecordingScrollViewInit"); + RecordingViewScrollView[RECORDINGVIEW] = new UIScrollView(); + if (RecordingViewScrollView[RECORDINGVIEW] == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingViewScrollView[RECORDINGVIEW] new fail!"); + return false; + } + RecordingViewScrollView[RECORDINGVIEW]->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + RecordingViewScrollView[RECORDINGVIEW]->SetScrollBlankSize(35); + RecordingViewScrollView[RECORDINGVIEW]->SetReboundSize(50); + RecordingViewScrollView[RECORDINGVIEW]->SetDirection(1); + RecordingViewScrollView[RECORDINGVIEW]->SetOnDragListener(presenter_); + RecordingViewScrollView[RECORDINGVIEW]->SetTouchable(true); + RecordingViewScrollView[RECORDINGVIEW]->SetDraggable(true); + return true; + } + + bool RecordingView::RecordingLabelViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView::RecordingLabelViewInit"); + if (RecordingViewTitleLabel == nullptr) + { + RecordingViewTitleLabel = new UILabelExt(); + if (RecordingViewTitleLabel == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingViewTitleLabel new fail!"); + return false; + } + } + RecordingViewTitleLabel->SetPosition(83, 50, 300, 35); + RecordingViewTitleLabel->SetStyle(STYLE_BACKGROUND_OPA, 0xff); + RecordingViewTitleLabel->SetStyle(STYLE_TEXT_FONT, 30); + RecordingViewTitleLabel->SetStyle(STYLE_LINE_HEIGHT, 35); + RecordingViewTitleLabel->SetTextId(STR_RECORDER); // 录音机 + RecordingViewTitleLabel->SetLineBreakMode(UILabel::LINE_BREAK_OSCILLATION); + RecordingViewTitleLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + RecordingViewTitleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); + /* -------------------------------------------------------------------------- */ + if (AttentionLabel == nullptr) + { + AttentionLabel = new UILabelExt(); + if (AttentionLabel == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AttentionLabel new fail!"); + return false; + } + } + AttentionLabel->SetPosition(53, 330, 360, 35); + AttentionLabel->SetStyle(STYLE_BACKGROUND_OPA, 0xff); + AttentionLabel->SetStyle(STYLE_TEXT_FONT, 30); + AttentionLabel->SetStyle(STYLE_LINE_HEIGHT, 35); + AttentionLabel->SetTextId(STR_CLICK_TO_RECORD); // 点击开始录音 + AttentionLabel->SetLineBreakMode(UILabel::LINE_BREAK_OSCILLATION); + AttentionLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + AttentionLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); + + return true; + } + + bool RecordingView::RecordingButtonViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView::RecordingButtonViewInit"); + ButtonConfig buttonconfig; + buttonconfig.x = 178; + buttonconfig.y = 150; + buttonconfig.w = 120; + buttonconfig.h = 120; + buttonconfig.ViewId = RECORD_BUTTON; + RecordingViewButton = SetTheButton(buttonconfig, presenter_); + if (RecordingViewButton == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingViewButton new fail!"); + return false; + } + + return true; + } + + bool RecordingView::RecordingImageViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView::RecordingImageViewInit"); + if (RECORD1_Image == nullptr) + { + RECORD1_Image = new UIImageView(); + if (RECORD1_Image == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RECORD1_Image new fail!"); + return false; + } + } + RECORD1_Image->SetPosition(158, 129, 150, 150); + RECORD1_Image->SetStyle(STYLE_BORDER_RADIUS, 10); + RECORD1_Image->SetSrc(PNG_RECORD1_IMAGE); + /* -------------------------------------------------------------------------- */ + if (pullUp_Image == nullptr) + { + pullUp_Image = new UIImageView(); + if (pullUp_Image == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "pullUp_Image new fail!"); + return false; + } + } + pullUp_Image->SetPosition(213, 400, 40, 40); + pullUp_Image->SetAutoEnable(false); + pullUp_Image->SetResizeMode(UIImageView::CONTAIN); + pullUp_Image->SetSrc("/user/res/Sleep/up.bin"); + + return true; + } + + // 录音视图初始化 + void RecordingView::RecordingViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingView::RecordingViewInit"); + // 如果其中任何一个初始化函数返回 false(即初始化失败),则会打印错误日志并返回空指针。 + if (!RecordingScrollViewInit() || !RecordingLabelViewInit() || + !RecordingButtonViewInit() || !RecordingImageViewInit()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingViewInit fail!!"); + return; + } + RecordingViewScrollView[RECORDINGVIEW]->Add(RecordingViewTitleLabel); + RecordingViewScrollView[RECORDINGVIEW]->Add(RECORD1_Image); + RecordingViewScrollView[RECORDINGVIEW]->Add(RecordingViewButton); + RecordingViewScrollView[RECORDINGVIEW]->Add(AttentionLabel); + RecordingViewScrollView[RECORDINGVIEW]->Add(pullUp_Image); + AddViewToRootContainer(RecordingViewScrollView[RECORDINGVIEW]); + } + + void RecordingView::OnStart() + { + RecordingViewInit(); + return; + } +} \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingVolumeSettingView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingVolumeSettingView.cpp new file mode 100644 index 000000000..3e67abfad --- /dev/null +++ b/code/sdk/application/wearable/fd230/nativeapp/nativeui/record/src/RecordingVolumeSettingView.cpp @@ -0,0 +1,74 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-03-13 17:38:18 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-08-26 18:16:06 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/record/src/RecordingVolumeSettingView.cpp + */ +#include "record/include/RecordingVolumeSettingView.h" +#include "record/include/RecordingPresenter.h" +#include "wearable_log.h" +#include "ConfigModel.h" +namespace OHOS +{ + + static RecordingVolumeSettingView *g_pRecordingVolumeSettingView{nullptr}; + RecordingVolumeSettingView::RecordingVolumeSettingView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingVolumeSettingView::RecordingVolumeSettingView"); + + g_pRecordingVolumeSettingView = this; + } + + RecordingVolumeSettingView::~RecordingVolumeSettingView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingVolumeSettingView::~RecordingVolumeSettingView"); + ClearAll(); + g_pRecordingVolumeSettingView = nullptr; + } + + RecordingVolumeSettingView *RecordingVolumeSettingView::GetInstance() + { + return g_pRecordingVolumeSettingView; + } + + void RecordingVolumeSettingView::ClearAll(void) + { + if (initViewStatus == true) + { + delete p_SoundAndVibrationVolumeSettingView; + p_SoundAndVibrationVolumeSettingView = nullptr; + } + } + + UIScrollView *RecordingVolumeSettingView::RecordingVolumeSettingViewInit(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RecordingVolumeSettingView::RecordingVolumeSettingViewInit"); + p_SoundAndVibrationVolumeSettingView = new SoundAndVibrationVolumeSettingView(SYSTEM_VOLUME); + if (p_SoundAndVibrationVolumeSettingView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "p_SoundAndVibrationVolumeSettingView nullptr err"); + return nullptr; + } + RecordingVolumeSettingViewScrollView = p_SoundAndVibrationVolumeSettingView->SetUpVolumeProcess(); + UIView::OnDragListener *volumeDragListener = static_cast(RecordingPresenter::GetInstance()); + if (volumeDragListener == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RecordingPresenter GetInstance fail"); + return nullptr; + } + RecordingVolumeSettingViewScrollView->SetOnDragListener(volumeDragListener); + if (RecordingVolumeSettingViewScrollView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "p_SoundAndVibrationVolumeSettingView->SetUpVolumeProcess fail!!"); + return nullptr; + } + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "volume:%d", AudioManager::GetInstance().GetVolume(AUDIO_STREAM_MUSIC)); + p_SoundAndVibrationVolumeSettingView->GetVolumeProcess()->SetValue(AudioManager::GetInstance().GetVolume(AUDIO_STREAM_MUSIC)); + + initViewStatus = true; + return RecordingVolumeSettingViewScrollView; + } + +} \ No newline at end of file -- 2.17.1