--- /dev/null
+\r
+\r
+#include "saveele/include/SaveBatView.h"\r
+#include "saveele/include/SaveEleModel.h"\r
+\r
+#include "common/image_cache_manager.h"\r
+#include "UiConfig.h"\r
+#include "ui_resource_image.h"\r
+#include <ui_scroll_view.h>\r
+#include <iostream>\r
+#include <chrono>\r
+#include <thread>\r
+//#include "battery_hal.h"\r
+#include "string"\r
+#include "custom_utils.h"\r
+#include "UiConfig.h"\r
+#include "wearable_log.h"\r
+\r
+#include "custom_runtime.h"\r
+#include "ConfigModel.h"\r
+#include "languagecode/LanguageInit.h"\r
+\r
+#define ANIMATION_TEST 0\r
+extern "C"\r
+{\r
+ void uapi_exit_power_saving_mode(void);\r
+ void uapi_enter_power_saving_mode(void);\r
+}\r
+\r
+std::string Cnweekday[] = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"}; \r
+std::string Enweekday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; \r
+\r
+static constexpr const char *WHITE_BATTERY = "/user/res/Battery/Battery_White.bin";\r
+static constexpr const char *SAVE_BUTTON = "/user/res/Save_Ele/finger.bin";\r
+static constexpr const char *BACK_BUTTON = "/user/res/Save_Ele/finger2.bin";\r
+static constexpr const char *SAVE_WATHCH = "/user/res/Save_Ele/wathch.bin";\r
+\r
+namespace OHOS\r
+{\r
+ /*动画类实现*/\r
+ const static int16_t CENTER_X = 233;\r
+ const static int16_t CENTER_Y = 233;\r
+ const static int16_t LABEL_X = 140;\r
+ const static int16_t LABEL_Y = 170;\r
+ const static int16_t RADIUS = 90; // 半径 90\r
+ const static int16_t STROKE_WIDTH = 20;\r
+ const static int16_t CIRCLE_BASE_WIDTH = 4;\r
+ const static uint32_t LIGHT_GREEN = 0xff007700;\r
+ static const uint16_t LABEL_FONT_SIZE = 80;\r
+ static const uint16_t ANIMATE_TIME = 500;\r
+ static const uint16_t SECOND_TO_MINISECOND = 1000;\r
+ static const uint16_t CIRCLE_FADE_OUT = 200;\r
+ static const uint16_t DEGREES_PER_CIRCLE = 360;\r
+ void CountdownBackAnimatorCallback::Callback(UIView *view)\r
+ {\r
+ // 根据当前阶段调用相应的功能,控制动画状态\r
+ switch (stage_)\r
+ {\r
+ case countStage::STAGE_GRADUAL_CIRCLE:\r
+ {\r
+ // 处理渐变圆圈绘制\r
+ GradualCircle();\r
+ break;\r
+ }\r
+ case countStage::STAGE_COUNTING_DOWN:\r
+ {\r
+ // 处理倒计时逻辑\r
+ CountingDown();\r
+ break;\r
+ }\r
+ case countStage::STAGE_FADE_OUT:\r
+ {\r
+ // 处理圆圈淡出效果\r
+ CircleFadeOut();\r
+ break;\r
+ }\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+\r
+ void CountdownBackAnimatorCallback::CircleFadeOut()\r
+ {\r
+ // 计算当前时间与上次更新时间的差值\r
+ uint32_t diffTime = HALTick::GetInstance().GetTime() - lastTime_;\r
+\r
+ // 如果尚未达到空闲时间,则什么也不做\r
+ if (diffTime < idleTime_)\r
+ {\r
+ return;\r
+ }\r
+\r
+ // 清空画布以准备绘制\r
+ canvas_->Clear();\r
+\r
+ // 计算当前的圆圈宽度\r
+ uint32_t curTime = diffTime - idleTime_;\r
+ uint16_t width;\r
+\r
+ // 判断是否已经达到淡出持续时间\r
+ if (curTime >= CIRCLE_FADE_OUT)\r
+ {\r
+ curTime = CIRCLE_FADE_OUT; // 限制为最大淡出时间\r
+ stage_ = countStage::STAGE_NONE; // 设置为无状态\r
+ }\r
+\r
+ // 使用缓动方程计算当前宽度\r
+ width = EasingEquation::QuadEaseInOut(STROKE_WIDTH, CIRCLE_BASE_WIDTH, curTime, CIRCLE_FADE_OUT);\r
+\r
+ // 绘制中心圆圈\r
+ Point center = {CENTER_X, CENTER_Y};\r
+ ColorType lightGreen;\r
+ lightGreen.full = LIGHT_GREEN;\r
+ PaintExt paint;\r
+ paint.SetStyle(Paint::PaintStyle::STROKE_STYLE);\r
+ paint.SetCapType(CAP_ROUND);\r
+ paint.SetAntialiased(true);\r
+ paint.SetStrokeColor(lightGreen);\r
+ paint.SetStrokeWidth(width);\r
+ canvas_->DrawCircle(center, RADIUS, paint);\r
+\r
+ // 更新标签的字体大小和透明度\r
+ uint16_t fontSize = LABEL_FONT_SIZE * width / STROKE_WIDTH; // 根据笔画宽度调整字体大小\r
+ uint16_t opa = OPA_OPAQUE * width / STROKE_WIDTH; // 根据笔画宽度调整透明度\r
+ if (stage_ == countStage::STAGE_NONE)\r
+ {\r
+ opa = OPA_TRANSPARENT; // 如果处于无状态,设置为完全透明\r
+ }\r
+\r
+ label_->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, fontSize);\r
+ label_->SetStyle(STYLE_TEXT_OPA, opa); // 更新标签样式\r
+ }\r
+\r
+ void CountdownBackAnimatorCallback::UpdateLable(uint32_t curTime)\r
+ {\r
+ char buf[2] = {0}; // 字符缓冲区,用于格式化标签文本\r
+ uint16_t fontSize; // 字体大小\r
+ uint16_t opa; // 透明度\r
+\r
+ // 前半段动画,字体逐渐变小\r
+ if (curTime < ANIMATE_TIME / 2)\r
+ {\r
+ fontSize = LABEL_FONT_SIZE - LABEL_FONT_SIZE * curTime * 2 / ANIMATE_TIME; // 计算当前字体大小\r
+ opa = OPA_OPAQUE * fontSize / LABEL_FONT_SIZE; // 计算当前透明度\r
+ if (firstArc_)\r
+ {\r
+ fontSize = fontSize / 2; // 如果是第一弧,字体设置为一半大小\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // 后半段动画,字体逐渐增大\r
+ fontSize = LABEL_FONT_SIZE * curTime * 2 / ANIMATE_TIME - LABEL_FONT_SIZE;\r
+ opa = OPA_OPAQUE * fontSize / LABEL_FONT_SIZE;\r
+\r
+ // 更新标签文本\r
+ if (updateText_)\r
+ {\r
+ if (sprintf_s(buf, sizeof(buf), "%u", (endAngle_ + easeDegree_) / degreePerSecond_) < 0)\r
+ {\r
+ return; // 如果 sprintf_s 出错,返回\r
+ }\r
+ label_->SetText(buf); // 设置标签文本为当前倒计时数字\r
+ updateText_ = false; // 更新文本之后将标志置为false\r
+ }\r
+ }\r
+\r
+ // 更新标签的字体和样式\r
+ label_->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, fontSize);\r
+ label_->SetStyle(STYLE_TEXT_OPA, opa);\r
+ }\r
+\r
+ void CountdownBackAnimatorCallback::UpdatePath(int16_t start, int16_t end, bool needDrawCircle)\r
+ {\r
+ // 计算绘制的圆心和颜色\r
+ Point center = {CENTER_X, CENTER_Y};\r
+ ColorType lightGreen;\r
+ lightGreen.full = LIGHT_GREEN;\r
+ PaintExt paint;\r
+ paint.SetStyle(Paint::PaintStyle::STROKE_STYLE);\r
+ paint.SetStrokeWidth(STROKE_WIDTH);\r
+ paint.SetCapType(CAP_ROUND);\r
+ paint.SetAntialiased(true);\r
+ paint.SetStrokeColor(lightGreen);\r
+\r
+ // 清空画布\r
+ canvas_->Clear();\r
+ // 如果需要绘制基础圆圈,则绘制\r
+ if (needDrawCircle)\r
+ {\r
+ canvas_->DrawCircle(center, RADIUS, paint);\r
+ }\r
+\r
+ // 如果起始角度与结束角度不相同,则绘制弧线\r
+ if (start != end)\r
+ {\r
+ paint.SetStrokeColor(Color::Green()); // 设置弧线颜色为绿色\r
+ // 如果起始角和结束角相差完整的一圈,则绘制完整的圆圈\r
+ if (end - start == DEGREES_PER_CIRCLE)\r
+ {\r
+ canvas_->DrawCircle(center, RADIUS, paint);\r
+ }\r
+ else\r
+ {\r
+ // 绘制从起始角到结束角\r
+ // 绘制从起始角到结束角的弧线\r
+ canvas_->DrawArc(center, RADIUS, start, end, paint);\r
+ }\r
+ }\r
+ }\r
+\r
+ void CountdownBackAnimatorCallback::CountingDown()\r
+ {\r
+ // 计算当前时间与上次更新时间的差值\r
+ uint32_t diffTime = HALTick::GetInstance().GetTime() - lastTime_;\r
+\r
+ // 如果时间差达到1秒,则更新倒计时\r
+ if (diffTime >= SECOND_TO_MINISECOND)\r
+ {\r
+ lastTime_ = HALTick::GetInstance().GetTime(); // 更新最后时间\r
+ // 判断是否是第一次绘制弧线\r
+ if (endAngle_ == DEGREES_PER_CIRCLE)\r
+ {\r
+ firstArc_ = true; // 如果是第一次,设置标志\r
+ }\r
+ else\r
+ {\r
+ firstArc_ = false; // 否则,设置为非第一次\r
+ }\r
+ // 更新路径和标签\r
+ UpdatePath(0, endAngle_, true);\r
+ UpdateLable(0);\r
+\r
+ // 如果倒计时结束,切换到淡出阶段\r
+ if (endAngle_ == 0)\r
+ {\r
+ stage_ = countStage::STAGE_FADE_OUT;\r
+ idleTime_ = SECOND_TO_MINISECOND - CIRCLE_FADE_OUT; // 设置空闲时间\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "倒计时结束");\r
+ OHOS::SaveEleModel::GetInstance()->SetBackState(true); // 进行界面弹出\r
+ return;\r
+ }\r
+\r
+ // 更新结束角度和缓动角度\r
+ easeDegree_ = degreePerSecond_;\r
+ endAngle_ -= degreePerSecond_; // 减少结束角度\r
+ // 如果结束角度小于等于剩余角度,则重置结束角度\r
+ if (endAngle_ <= surplusDegree)\r
+ {\r
+ endAngle_ = 0;\r
+ easeDegree_ += surplusDegree; // 增加缓动角度\r
+ }\r
+ updateText_ = true; // 标记需要更新文本\r
+ }\r
+ else if (diffTime >= idleTime_)\r
+ {\r
+ // 如果时间差超过空闲时间,更新路径和标签\r
+ uint32_t curTime = diffTime - idleTime_;\r
+ int16_t arcCurr = EasingEquation::QuadEaseInOut(0, easeDegree_, curTime, ANIMATE_TIME);\r
+ UpdatePath(0, endAngle_ + easeDegree_ - arcCurr, true);\r
+ UpdateLable(curTime);\r
+ }\r
+ }\r
+\r
+ void CountdownBackAnimatorCallback::GradualCircle()\r
+ {\r
+ // 计算当前时间与上次更新时间的差值\r
+ uint32_t diffTime = HALTick::GetInstance().GetTime() - lastTime_;\r
+\r
+ // 如果时间差达到1秒,则切换到倒计时阶段\r
+ if (diffTime >= SECOND_TO_MINISECOND)\r
+ {\r
+ stage_ = countStage::STAGE_COUNTING_DOWN; // 切换阶段\r
+ idleTime_ = SECOND_TO_MINISECOND - ANIMATE_TIME; // 设置空闲时间\r
+ }\r
+ else if (diffTime >= idleTime_)\r
+ {\r
+ // 如果时间差超过空闲时间,绘制渐变圆圈\r
+ uint32_t curTime = diffTime - idleTime_;\r
+ int16_t arcCurr = EasingEquation::QuadEaseInOut(0, DEGREES_PER_CIRCLE,\r
+ curTime, SECOND_TO_MINISECOND - idleTime_);\r
+ UpdatePath(180, arcCurr + 180, false); // 从180度开始绘制\r
+ }\r
+ }\r
+\r
+ void CountdownBackAnimatorCallback::SetInfo(UILabel *label, int counts)\r
+ {\r
+ // 设置标签和计数值\r
+ counts_ = counts; // 记录倒计时的总次数\r
+ label_ = label; // 记录UILabel对象\r
+ }\r
+\r
+ void CountdownBackAnimatorCallback::NotifyStart()\r
+ {\r
+ // 初始化倒计时动画的状态\r
+ stage_ = countStage::STAGE_GRADUAL_CIRCLE; // 设置为渐变圆圈阶段\r
+ endAngle_ = DEGREES_PER_CIRCLE; // 设置结束角度为完整一圈\r
+ idleTime_ = 200; // 设置初始空闲时间\r
+ degreePerSecond_ = DEGREES_PER_CIRCLE / counts_; // 计算每秒减少的角度\r
+ surplusDegree = DEGREES_PER_CIRCLE - degreePerSecond_ * counts_; // 计算剩余角度\r
+ lastTime_ = HALTick::GetInstance().GetTime(); // 记录当前时间\r
+\r
+ // 初始化标签文本和样式\r
+ label_->SetText(" ");\r
+ label_->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, LABEL_FONT_SIZE / 2); // 设置字体为一半大小\r
+ label_->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); // 设置标签为不透明\r
+ }\r
+\r
+ void CountdownBackAnimatorCallback::CancelCountdown()\r
+ {\r
+ // 设置阶段为淡出\r
+ stage_ = countStage::STAGE_FADE_OUT;\r
+\r
+ // 重置时间以立即开始淡出\r
+ lastTime_ = HALTick::GetInstance().GetTime(); // 记录当前时间\r
+ idleTime_ = 0; // 设置空闲时间为零,以跳过任何等待时间\r
+\r
+ endAngle_ = 0; // 设置结束角度为0,表示取消倒计时\r
+ }\r
+\r
+ static SaveBatView *g_pSaveBatView{nullptr};\r
+\r
+ SaveBatView::SaveBatView()\r
+ {\r
+ /*开启省电模式*/\r
+ uapi_enter_power_saving_mode();\r
+\r
+ g_pSaveBatView = this;\r
+ }\r
+\r
+\r
+ SaveBatView::~SaveBatView() \r
+ { \r
+ /* 关闭省电模式 */ \r
+ uapi_exit_power_saving_mode();\r
+\r
+ // UIViewGroup *tmpGroup = dynamic_cast<UIViewGroup *>(container_);\r
+ // UIViewGroup::RemoveAndDeleteAllRecursively(tmpGroup);\r
+\r
+ // 释放所有动态分配的成员变量 \r
+ if (timelabel) { \r
+ delete timelabel; \r
+ timelabel = nullptr; \r
+ } \r
+ if (datelabel) { \r
+ delete datelabel; \r
+ datelabel = nullptr; \r
+ } \r
+ if (batterylabel) { \r
+ delete batterylabel; \r
+ batterylabel = nullptr; \r
+ } \r
+ if (batteryprogress) { \r
+ delete batteryprogress; \r
+ batteryprogress = nullptr; \r
+ } \r
+ if (batteryiamge) { \r
+ delete batteryiamge; \r
+ batteryiamge = nullptr; \r
+ } \r
+ if (button_exit) { \r
+ delete button_exit; \r
+ button_exit = nullptr; \r
+ } \r
+\r
+ // 退出界面的成员变量 \r
+ if (curren_label) { \r
+ delete curren_label; \r
+ curren_label = nullptr; \r
+ } \r
+ if (countlabel) { \r
+ delete countlabel; \r
+ countlabel = nullptr; \r
+ } \r
+ if (wathchiamge) { \r
+ delete wathchiamge; \r
+ wathchiamge = nullptr; \r
+ } \r
+ if (backprogress) { \r
+ delete backprogress; \r
+ backprogress = nullptr; \r
+ } \r
+\r
+ // 测试相关的成员变量 \r
+ if (CountdownBackAnimator_) {\r
+ CountdownBackAnimator_->Stop();\r
+ }\r
+ if (callBack_) { \r
+ delete callBack_; \r
+ callBack_ = nullptr;\r
+ }\r
+ \r
+ delete CountdownBackAnimator_;\r
+ CountdownBackAnimator_ = nullptr;\r
+ \r
+ if (canvas_) { \r
+ delete canvas_; \r
+ canvas_ = nullptr; \r
+ } \r
+ if (restart_) { \r
+ delete restart_; \r
+ restart_ = nullptr; \r
+ } \r
+ \r
+ if (label_) { \r
+ delete label_; \r
+ label_ = nullptr; \r
+ } \r
+\r
+ // 将全局指针设为 nullptr \r
+ g_pSaveBatView = nullptr; \r
+ }\r
+\r
+ SaveBatView *SaveBatView::GetInstance()\r
+ {\r
+ return g_pSaveBatView;\r
+ }\r
+\r
+ /* 更新主界面数据 */\r
+ void SaveBatView::Refresh_Dial_View()\r
+ {\r
+ /*\r
+ 日期样式 04-22 周五\r
+ 时间样式 09:10\r
+ */\r
+ if (timelabel == nullptr || datelabel == nullptr || batterylabel == nullptr || batteryprogress == nullptr)\r
+ return;\r
+\r
+ // 获取当前时间\r
+ time_t seconds;\r
+ time(&seconds);\r
+ struct tm pTM;\r
+ localtime_r(&seconds, &pTM);\r
+\r
+ // 解析时间\r
+ int hour = pTM.tm_hour;\r
+ int minute = pTM.tm_min;\r
+ int day = pTM.tm_mday;\r
+ int month = pTM.tm_mon + 1; // 月份范围 [1, 12]\r
+ std::string weekStr;\r
+ if (ConfigModel::GetInstance()->GetLanguage() == ZH_CN)\r
+ weekStr = Cnweekday[pTM.tm_wday];\r
+ else\r
+ weekStr = Enweekday[pTM.tm_wday];\r
+ \r
+ // 构建日期和时间字符串\r
+ std::string dateStr =\r
+ (month < 10 ? "0" : "") + std::to_string(month) + "-" +\r
+ (day < 10 ? "0" : "") + std::to_string(day) + " " + weekStr;\r
+\r
+ //需要判断显示的格式\r
+ if (uapi_dev_runtime_get_time_hour_show_model() == 12)\r
+ {\r
+ if (pTM.tm_hour > 12)\r
+ hour = pTM.tm_hour - 12 ;\r
+ }\r
+ \r
+ std::string stringtime =\r
+ (hour < 10 ? "0" : "") + std::to_string(hour) + ":" +\r
+ (minute < 10 ? "0" : "") + std::to_string(minute);\r
+\r
+ // 获取电量值\r
+ float voltage = 0.0F;\r
+ //uint8_t value = battery_get_voltage(&voltage);\r
+ uint8_t value = 0;\r
+\r
+ \r
+ // 更新界面组件\r
+ timelabel->SetText(stringtime.c_str());\r
+ datelabel->SetText(dateStr.c_str());\r
+ batterylabel->SetText((std::to_string(value) + "%").c_str());\r
+ batteryprogress->SetValue(value);\r
+ }\r
+\r
+ void SaveBatView::InitBatteryView()\r
+ {\r
+ // 创建电池框图像\r
+ batteryiamge = new UIImageView();\r
+ if (!batteryiamge)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "batteryiamge creation failed");\r
+ return;\r
+ }\r
+\r
+ // 创建电池进度条\r
+ batteryprogress = new UIBoxProgress();\r
+ if (!batteryprogress)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "batteryprogress creation failed");\r
+ return;\r
+ }\r
+\r
+ // 创建电池标签\r
+ batterylabel = new UILabel();\r
+ if (!batterylabel)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "batterylabel creation failed");\r
+ return;\r
+ }\r
+\r
+ // 设置位置\r
+ batteryiamge->SetPosition(176, 52, 100, 100);\r
+ batteryiamge->SetSrc(WHITE_BATTERY);\r
+\r
+ batteryprogress->SetPosition(182, 58, 30, 18);\r
+ batteryprogress->SetStyle(STYLE_BORDER_RADIUS, 20);\r
+ batteryprogress->SetViewId("batteryprogress");\r
+ batteryprogress->SetStyle(STYLE_BACKGROUND_OPA, 0xff);\r
+\r
+ batterylabel->SetPosition(228, 54, 200, 60);\r
+ batterylabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, 26);\r
+ batterylabel->SetTextColor(Color::White());\r
+ batteryprogress->SetForegroundStyle(STYLE_BACKGROUND_COLOR, 0xffffc300);\r
+\r
+ AddViewToRootContainer(batteryiamge);\r
+ AddViewToRootContainer(batterylabel);\r
+ AddViewToRootContainer(batteryprogress);\r
+ }\r
+ void SaveBatView::InitTimeView()\r
+ {\r
+ /*时间time*/\r
+ timelabel = new UILabel();\r
+ if (timelabel == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "timelabel creation failed");\r
+ return;\r
+ }\r
+ timelabel->SetPosition(0, 148);\r
+ timelabel->Resize(466, 100);\r
+ timelabel->SetViewId("label1");\r
+ timelabel->SetStyle(STYLE_TEXT_FONT, 100);\r
+ timelabel->SetText("11:00");\r
+ timelabel->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS);\r
+ timelabel->SetTextColor(Color::GetColorFromRGBA(0x49, 0xef, 0x13, 0xff));\r
+ timelabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);\r
+ timelabel->SetRollSpeed(0);\r
+ timelabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, 100);\r
+ AddViewToRootContainer(timelabel);\r
+\r
+ /*日期*/\r
+ datelabel = new UILabel();\r
+ if (datelabel == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "datelabel creation failed");\r
+ return;\r
+ }\r
+ datelabel->SetPosition(83, 258);\r
+ datelabel->Resize(300, 60);\r
+ datelabel->SetViewId("label2");\r
+ datelabel->SetStyle(STYLE_TEXT_FONT, 30);\r
+\r
+ // datelabel->SetText("04-22 周五");\r
+ datelabel->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS);\r
+ datelabel->SetTextColor(Color::GetColorFromRGBA(0x66, 0x66, 0x66, 0xff));\r
+ datelabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);\r
+ datelabel->SetRollSpeed(0);\r
+ datelabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, 30);\r
+ AddViewToRootContainer(datelabel);\r
+ }\r
+ void SaveBatView::InitButtonView()\r
+ {\r
+ // 初始化按键\r
+ button_exit = new UIButton();\r
+ if (button_exit == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "button_exit creation failed");\r
+ return;\r
+ }\r
+ button_exit->SetPosition(204, 350);\r
+ button_exit->Resize(100, 100);\r
+ button_exit->SetViewId("button_exit");\r
+ button_exit->SetStyle(STYLE_BACKGROUND_COLOR, 0xff000000);\r
+ button_exit->SetStyle(STYLE_BACKGROUND_OPA, 0x00);\r
+\r
+ button_exit->SetImageSrc(SAVE_BUTTON, SAVE_BUTTON);\r
+ button_exit->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff000000, UIButton::PRESSED);\r
+\r
+ button_exit->SetOnTouchListener(presenter_);\r
+ AddViewToRootContainer(button_exit);\r
+ }\r
+ void SaveBatView::InitShowBackView()\r
+ {\r
+ // 时间\r
+ time_t seconds;\r
+ time(&seconds);\r
+ struct tm pTM;\r
+ localtime_r(&seconds, &pTM);\r
+\r
+ int hour = pTM.tm_hour;\r
+ int minute = pTM.tm_min;\r
+ std::string stringtime =\r
+ (hour < 10 ? "0" : "") + std::to_string(hour) + ":" +\r
+ (minute < 10 ? "0" : "") + std::to_string(minute);\r
+\r
+ curren_label = new UILabel();\r
+ if (curren_label == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "curren_label creation failed");\r
+ return;\r
+ }\r
+ curren_label->SetPosition(181, 52);\r
+ curren_label->Resize(200, 60);\r
+ curren_label->SetViewId("label4");\r
+ curren_label->SetStyle(STYLE_TEXT_FONT, 40);\r
+ curren_label->SetText(stringtime.c_str());\r
+ curren_label->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT);\r
+ curren_label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);\r
+ curren_label->SetRollSpeed(0);\r
+ curren_label->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, 40);\r
+ AddViewToRootContainer(curren_label);\r
+ curren_label->SetVisible(false);\r
+#if ANIMATION_TEST\r
+ // 圆形进度条\r
+ backprogress = new UICircleProgress();\r
+ if (backprogress == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "backprogress creation failed");\r
+ return;\r
+ }\r
+ backprogress->SetPosition(143, 143);\r
+ backprogress->Resize(183, 186);\r
+ backprogress->SetViewId("circleProgress1");\r
+ backprogress->SetStyle(STYLE_BACKGROUND_OPA, 0x00); // 确保背景透明\r
+ backprogress->SetBackgroundStyle(STYLE_BACKGROUND_COLOR, 0x00000000); // 背景颜色设置为完全透明\r
+ backprogress->SetBackgroundStyle(STYLE_LINE_WIDTH, 20);\r
+ backprogress->SetForegroundStyle(STYLE_BACKGROUND_COLOR, 0xff000000);\r
+ backprogress->SetForegroundStyle(STYLE_BORDER_COLOR, 0xff000000);\r
+ backprogress->SetForegroundStyle(STYLE_LINE_COLOR, 0xff18ef05);\r
+ backprogress->SetForegroundStyle(STYLE_LINE_WIDTH, 20);\r
+ backprogress->SetCenterPosition(92, 93);\r
+ backprogress->SetRadius(90);\r
+ backprogress->SetEndAngle(359);\r
+ backprogress->SetValue(0);\r
+ container_->Add(backprogress);\r
+ backprogress->SetVisible(false);\r
+\r
+ // 手表image\r
+ wathchiamge = new UIImageView();\r
+ if (wathchiamge == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "wathchiamge creation failed");\r
+ return;\r
+ }\r
+ wathchiamge->SetPosition(191, 182);\r
+ wathchiamge->Resize(100, 100);\r
+ wathchiamge->SetViewId("image1");\r
+ wathchiamge->SetSrc(SAVE_WATHCH);\r
+ container_->Add(wathchiamge);\r
+ wathchiamge->SetVisible(false);\r
+\r
+ // 倒计时\r
+ countlabel = new UILabel();\r
+ if (countlabel == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "countlabel creation failed");\r
+ return;\r
+ }\r
+ countlabel->SetPosition(221, 212);\r
+ countlabel->Resize(200, 60);\r
+ countlabel->SetViewId("label3");\r
+ countlabel->SetStyle(STYLE_TEXT_FONT, 40);\r
+ countlabel->SetText("3");\r
+ countlabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT);\r
+ countlabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);\r
+ countlabel->SetRollSpeed(0);\r
+ countlabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, 40);\r
+ container_->Add(countlabel);\r
+ countlabel->SetVisible(false);\r
+#else\r
+ if (canvas_ == nullptr)\r
+ {\r
+ canvas_ = new UICanvasExt();\r
+ }\r
+ canvas_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());\r
+ canvas_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);\r
+ AddViewToRootContainer(canvas_);\r
+ canvas_->SetVisible(false);\r
+\r
+ if (label_ == nullptr)\r
+ {\r
+ label_ = new UILabel();\r
+ }\r
+ label_->SetPosition(LABEL_X, LABEL_Y, 180, 120);\r
+ label_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);\r
+ AddViewToRootContainer(label_);\r
+ label_->SetVisible(false);\r
+\r
+ PaintExt paint;\r
+ ColorType lightGreen;\r
+ lightGreen.full = LIGHT_GREEN;\r
+ paint.SetStyle(Paint::PaintStyle::STROKE_STYLE);\r
+ paint.SetStrokeWidth(CIRCLE_BASE_WIDTH);\r
+ paint.SetAntialiased(true);\r
+ paint.SetStrokeColor(lightGreen);\r
+ canvas_->DrawCircle({CENTER_X, CENTER_Y}, RADIUS, paint);\r
+\r
+ callBack_ = new CountdownBackAnimatorCallback(canvas_);\r
+ if (callBack_ == nullptr)\r
+ {\r
+ GRAPHIC_LOGE("CallBack new fail");\r
+ return;\r
+ }\r
+ CountdownBackAnimator_ = new Animator(callBack_, canvas_, 0, true);\r
+ if (CountdownBackAnimator_ == nullptr)\r
+ {\r
+ delete callBack_;\r
+ callBack_ = nullptr;\r
+ GRAPHIC_LOGE("Animator new fail");\r
+ return;\r
+ }\r
+ CountdownBackAnimator_->Start();\r
+ callBack_->SetInfo(label_, 3); // 3: countdown numbers\r
+#endif\r
+ }\r
+\r
+ // 更新当前界面状态\r
+ void SaveBatView::UpdateView()\r
+ {\r
+ bool state = SaveEleModel::GetInstance()->GetViewState();\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateView state %d", state);\r
+\r
+ // 检查每个组件是否为空,并记录具体信息\r
+ if (timelabel == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "timelabel is null");\r
+ return;\r
+ }\r
+ if (datelabel == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "datelabel is null");\r
+ return;\r
+ }\r
+ if (batterylabel == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "batterylabel is null");\r
+ return;\r
+ }\r
+ if (batteryprogress == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "batteryprogress is null");\r
+ return;\r
+ }\r
+ if (batteryiamge == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "batteryiamge is null");\r
+ return;\r
+ }\r
+ if (curren_label == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "curren_label is null");\r
+ return;\r
+ }\r
+#if ANIMATION_TEST\r
+ if (countlabel == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "countlabel is null");\r
+ return;\r
+ }\r
+ if (wathchiamge == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "wathchiamge is null");\r
+ return;\r
+ }\r
+ if (backprogress == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "backprogress is null");\r
+ return;\r
+ }\r
+#endif\r
+ if (button_exit == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "button_exit is null");\r
+ return;\r
+ }\r
+\r
+ // 显示/隐藏原界面组件\r
+ bool showPrimaryView = !state;\r
+ timelabel->SetVisible(showPrimaryView);\r
+ datelabel->SetVisible(showPrimaryView);\r
+ batterylabel->SetVisible(showPrimaryView);\r
+ batteryprogress->SetVisible(showPrimaryView);\r
+ batteryiamge->SetVisible(showPrimaryView);\r
+\r
+#if ANIMATION_TEST\r
+ // 初始化计数器\r
+ int count = 3;\r
+ int progressValue = 0;\r
+ countlabel->SetText(std::to_string(count).c_str());\r
+ backprogress->SetValue(progressValue);\r
+\r
+ /* 退出界面 */\r
+ curren_label->SetVisible(state);\r
+ countlabel->SetVisible(state);\r
+ wathchiamge->SetVisible(state);\r
+ backprogress->SetVisible(state);\r
+\r
+#else\r
+ /* 退出界面 */\r
+ curren_label->SetVisible(state);\r
+\r
+ // 显示当前时间\r
+ time_t seconds;\r
+ time(&seconds);\r
+ struct tm pTM;\r
+ localtime_r(&seconds, &pTM);\r
+\r
+ int hour = pTM.tm_hour;\r
+ int minute = pTM.tm_min;\r
+ std::string stringtime =\r
+ (hour < 10 ? "0" : "") + std::to_string(hour) + ":" +\r
+ (minute < 10 ? "0" : "") + std::to_string(minute);\r
+ curren_label->SetText(stringtime.c_str());\r
+ label_->SetVisible(state);\r
+ canvas_->SetVisible(state);\r
+\r
+#endif\r
+\r
+ // 设置退出按钮图像\r
+ const char *buttonImage = state ? BACK_BUTTON : SAVE_BUTTON;\r
+ button_exit->SetImageSrc(buttonImage, buttonImage);\r
+ }\r
+\r
+ /*动画的控制*/\r
+ void SaveBatView::StartCanvas()\r
+ {\r
+ callBack_->NotifyStart();\r
+ }\r
+ void SaveBatView::StopCanvas()\r
+ {\r
+ callBack_->CancelCountdown();\r
+ }\r
+\r
+ void SaveBatView::OnStart()\r
+ {\r
+ \r
+\r
+ GetRootContainer()->SetPosition(0, 0);\r
+ GetRootContainer()->SetWidth(Screen::GetInstance().GetWidth());\r
+ GetRootContainer()->SetHeight(Screen::GetInstance().GetHeight());\r
+ GetRootContainer()->SetTouchable(true);\r
+ GetRootContainer()->SetDraggable(true);\r
+\r
+ InitBatteryView();\r
+ InitTimeView();\r
+ InitButtonView();\r
+ InitShowBackView();\r
+\r
+ Draw();\r
+\r
+ //SetContainerView(container_);\r
+ //RootView::GetInstance()->SetOnKeyActListener(presenter_);\r
+ }\r
+\r
+ \r
+}
\ No newline at end of file
--- /dev/null
+/***\r
+ * @Date: 2024-04-15 10:55:58\r
+ * @LastEditors: Caisking 3449750381@qq.com\r
+ * @LastEditTime: 2024-08-09 14:41:32\r
+ * @FilePath:\r
+ * /FD230/code/sdk/application/wearable/fd230app/nativeui/saveele/src/SaveEleView.cpp\r
+ */\r
+\r
+#include "saveele/include/SaveEleView.h"\r
+#include "saveele/include/SaveElePresenter.h"\r
+\r
+#include "UiConfig.h"\r
+#include "common/image_cache_manager.h"\r
+#include "components/ui_button.h"\r
+#include "components/ui_scroll_view.h"\r
+#include "ui_resource_image.h"\r
+#include "ui_resource_string.h"\r
+#include "uicomponents/UIComponents.h"\r
+#include "components/ui_scroll_view.h"\r
+\r
+namespace OHOS {\r
+\r
+static SaveEleView *g_pSaveEleView{nullptr};\r
+static const uint32_t BACK_GROUND_COLOR = 0xfff6f6f6;\r
+\r
+static constexpr char *iconImgPath = "/user/res/Save_Ele/SaveEle.bin";\r
+static constexpr char *butnoImgPath = "/user/res/Save_Ele/Save_Error.bin";\r
+static constexpr char *butokImgPath = "/user/res/Save_Ele/Save_Right.bin";\r
+\r
+SaveEleView::SaveEleView() { g_pSaveEleView = this; }\r
+\r
+SaveEleView::~SaveEleView() {\r
+\r
+ // UIViewGroup *tmpGroup = dynamic_cast<UIViewGroup *>(container_);\r
+ // UIViewGroup::RemoveAndDeleteAllRecursively(tmpGroup);\r
+\r
+ if (scrollview_ != nullptr) {\r
+ scrollview_->RemoveAll();\r
+ delete scrollview_;\r
+ scrollview_ = nullptr;\r
+ }\r
+ RootView::GetInstance()->RemoveAll();\r
+ \r
+ if (labeltitle) {\r
+ delete labeltitle;\r
+ labeltitle = nullptr;\r
+ }\r
+ if (labelnote) {\r
+ delete labelnote;\r
+ labelnote = nullptr;\r
+ }\r
+ if (labelkown) {\r
+ delete labelkown;\r
+ labelkown = nullptr;\r
+ }\r
+ if (iamgeicon) {\r
+ delete iamgeicon;\r
+ iamgeicon = nullptr;\r
+ }\r
+ if (buttonno) {\r
+ delete buttonno;\r
+ buttonno = nullptr;\r
+ }\r
+ if (buttonok) {\r
+ delete buttonok;\r
+ buttonok = nullptr;\r
+ }\r
+\r
+ g_pSaveEleView = nullptr;\r
+}\r
+\r
+SaveEleView *SaveEleView::GetInstance() { return g_pSaveEleView; }\r
+\r
+void SaveEleView::InitView() {\r
+ \r
+ SaveEleView_ = new UIScrollView();\r
+ SaveEleView_->SetPosition(0, 0, 466, 466);\r
+ SaveEleView_->SetStyle(STYLE_BACKGROUND_OPA, 0);\r
+ \r
+\r
+ /*初始化label*/\r
+ InitRollLabel(labeltitle, 83, 50, 300, 35, "labletitle", STR_POWER_SAVE_MODE,\r
+ DEFAULT_VECTOR_FONT_FILENAME, 30);\r
+ // TODO:多国语言\r
+ InitLabelExt(labelnote, 53, 217, 360, 200, "labletitle", STR_SAVENOTE,\r
+ DEFAULT_VECTOR_FONT_FILENAME, 30);\r
+ labelnote->SetLineBreakMode(UILabel::LINE_BREAK_WRAP);\r
+\r
+ InitLabelExt(labelkown, 53, labelnote->GetY() + labelnote->GetHeight() + 20,\r
+ 360, 100, "labelrecord", STR_SAVEBACK,\r
+ DEFAULT_VECTOR_FONT_FILENAME, 30);\r
+ labelkown->SetLineBreakMode(UILabel::LINE_BREAK_WRAP);\r
+ labelkown->SetTextColor(Color::Orange());\r
+\r
+ /*初始化图片*/\r
+ InitImageView(iamgeicon, 188, 121, 80, 90, "saveicon", iconImgPath);\r
+\r
+ /*初始化按键*/\r
+ InitButton(buttonno, 110, labelkown->GetY() + labelkown->GetHeight() + 40,\r
+ 100, 100, SAVEBUTTONNO);\r
+ buttonno->SetImageSrc(butnoImgPath, butnoImgPath);\r
+ buttonno->SetOnClickListener(presenter_);\r
+\r
+ InitButton(buttonok, 255, labelkown->GetY() + labelkown->GetHeight() + 40,\r
+ 100, 100, SAVEBUTTONOK);\r
+ buttonok->SetImageSrc(butokImgPath, butokImgPath);\r
+ buttonok->SetOnClickListener(presenter_);\r
+\r
+ SaveEleView_->Add(labeltitle);\r
+ SaveEleView_->Add(labelnote);\r
+ SaveEleView_->Add(labelkown);\r
+ SaveEleView_->Add(iamgeicon);\r
+ SaveEleView_->Add(buttonno);\r
+ SaveEleView_->Add(buttonok);\r
+ scrollview_->Add(SaveEleView_);\r
+ \r
+}\r
+\r
+void SaveEleView::OnStart() {\r
+\r
+ View<SaveElePresenter>::OnStart();\r
+ \r
+ scrollview_ = new UIScrollView();\r
+ if (scrollview_ == nullptr) {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "scrollview_ new fail");\r
+ return;\r
+ }\r
+ scrollview_->SetScrollBlankSize(35);\r
+ scrollview_->SetReboundSize(50);\r
+ scrollview_->SetPosition(0, 0, Screen::GetInstance().GetWidth(),\r
+ Screen::GetInstance().GetHeight());\r
+\r
+ scrollview_->SetOnDragListener(presenter_);\r
+ scrollview_->SetOnRotateListener(presenter_);\r
+ scrollview_->SetRotateFactor(2);\r
+ scrollview_->RequestFocus();\r
+ scrollview_->SetTouchable(true);\r
+ scrollview_->SetDraggable(true);\r
+ scrollview_->SetStyle(STYLE_BACKGROUND_COLOR, BACK_GROUND_COLOR);\r
+ scrollview_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);\r
+\r
+\r
+ AddViewToRootContainer(scrollview_);\r
+ InitView();\r
+ \r
+}\r
+\r
+\r
+} // namespace OHOS\r