/*---------------------------------------------------------------------------- * Copyright (c) TJD Technologies Co., Ltd. 2025. All rights reserved. * * Description: TjdUiAppDockView.cpp * * Author: luziquan@ss-tjd.com * * Create: 2024-06-15 *--------------------------------------------------------------------------*/ #include "TjdUiAppDockView.h" #include "NativeAbility.h" #include "TjdUiAppListModel.h" #include "TjdUiImageIds.h" #include "TjdUiMemManage.h" #include "TjdUiMultiLanguageExt.h" #include "common/image_cache_manager.h" #include "gfx_utils/mem_check.h" #include "sys_config.h" #include #include namespace TJD { #define ENABLE_PRINT_INFO 1 #if ENABLE_PRINT_INFO #define static_print_info(...) sys_ui_log_i(__VA_ARGS__) // 一般信息打印宏控制 #define static_print_warn(...) sys_ui_log_w(__VA_ARGS__) // 警告信息打印一般常开 #define static_print_error(...) sys_ui_log_e(__VA_ARGS__) // 错误信息打印一般常开 #define static_print_debug(...) sys_ui_log_d(__VA_ARGS__) // 调试信息打印一般常开 #else #define static_print_info(...) #define static_print_warn(...) #define static_print_error(...) #define static_print_debug(...) #endif #define DOCK_IMAGE_BIN_PATH TJD_IMAGE_PATH "img_dock.bin" static TjdUiAppDockView *g_dockView = nullptr; static constexpr uint8_t DIVISOR_TWO = 2; static constexpr uint16_t PAGE_WIDTH = 280; static constexpr uint16_t PAGE_HEIGHT = 280; TjdUiAppDockView::TjdUiAppDockView() { g_dockView = this; } TjdUiAppDockView::~TjdUiAppDockView() { g_dockView = nullptr; } TjdUiAppDockView *TjdUiAppDockView::GetInstance(void) { return g_dockView; } struct sliceIdMap { uint16_t sliceId; int resId; }; std::unordered_map *g_sliceInfoMap = nullptr; static SliceInfo FindDockItenInfo(uint16_t sliceId) { TjdUiAppListModel &appListModel = TjdUiAppListModel::GetInstance(); SliceInfo info = {.sliceId = sliceId, .resId = 0, .nameId = STR_MAX_ID}; const TjdAppItem *appList = appListModel.GetApplistItems(); if (g_sliceInfoMap == nullptr || appList == nullptr) { return info; } for (uint8_t i = 0; i < appListModel.GetAppListNum(); i++) { if (appList[i].appItem.id == sliceId) { info.nameId = appList[i].txtId; } } if (g_sliceInfoMap->find(sliceId) != g_sliceInfoMap->end()) { info.resId = g_sliceInfoMap->at(sliceId); return info; } return info; } void TjdUiAppDockView::InitDockItemInfo() { if (g_sliceInfoMap == nullptr) { g_sliceInfoMap = new std::unordered_map(); } std::unordered_map tempMap = {{TJD_APP_VIEW_HR, IMG_DOCK_HR}, {TJD_APP_VIEW_SPO2, IMG_DOCK_BO}, {TJD_APP_VIEW_STRESS, IMG_DOCK_PRESSURE}, {TJD_APP_VIEW_PLAYER, IMG_DOCK_MUSIC}, {TJD_APP_VIEW_SETTING, IMG_DOCK_SETTING}, {TJD_APP_VIEW_WEATHER, IMG_DOCK_WEATHER}, {TJD_APP_VIEW_BREATHING, IMG_DOCK_BREATHING}, {TJD_APP_VIEW_COMPASS, IMG_DOCK_COMPASS}, {TJD_APP_VIEW_STOPWATCH, IMG_DOCK_STOPWATCH}, {TJD_APP_VIEW_DAILYDATA, IMG_DOCK_DATA}, {TJD_APP_VIEW_BUSINESSCARD, IMG_DOCK_BUSINESS_CARD}, {TJD_APP_VIEW_WALLET, IMG_DOCK_CARD_BAG}, {TJD_APP_VIEW_CAMERA, IMG_DOCK_CAMERA}, {TJD_APP_VIEW_VOICE_ASSISTANT, IMG_DOCK_SIRI}, {TJD_APP_VIEW_GAME, IMG_DOCK_GAME}, {TJD_APP_VIEW_LUCKY_CLOVER, IMG_DOCK_CLOVER}, {TJD_APP_VIEW_SLEEP, IMG_DOCK_SLEEP}, {TJD_APP_VIEW_SPORT, IMG_DOCK_SPORT}, {TJD_APP_VIEW_MESSAGE_TOTAL, IMG_DOCK_INFORMATION}, {TJD_APP_VIEW_ALBUM, IMG_DOCK_ALBUM}, {TJD_APP_VIEW_ALIPAY, IMG_DOCK_ALIPAY}, {TJD_APP_VIEW_PLAY_DIAL, IMG_DOCK_CLOCK_DIAL}, {TJD_APP_VIEW_SPORT_RECORD, IMG_DOCK_SPORTS_RECORD}, {TJD_APP_VIEW_CALENDAR, IMG_DOCK_CALENDAR}, {TJD_APP_VIEW_RECORD, IMG_DOCK_SOUND_RECORDING}, {TJD_APP_VIEW_CALCULATOR, IMG_DOCK_CALCULATOR}, {TJD_APP_VIEW_PHONE, IMG_DOCK_PHONE}, {TJD_APP_VIEW_FEMALE, IMG_DOCK_PHYSIOLOGICAL_CYCLE}, {TJD_APP_VIEW_MS_GAME, IMG_DOCK_SENSORY_GAMES}, {TJD_APP_VIEW_TIMER, IMG_DOCK_TIMER}, {TJD_APP_VIEW_EBOOK, IMG_DOCK_EBOOK}, {TJD_APP_VIEW_ALARM, IMG_DOCK_ALARM_CLOCK}, {TJD_APP_VIEW_LEFUN_AI, IMG_DOCK_LEFUN_AI}}; g_sliceInfoMap->insert(tempMap.begin(), tempMap.end()); } void TjdUiAppDockView::OnStart() { InitDockItemInfo(); if (container_ == nullptr) { container_ = new OHOS::UIScrollView(); container_->SetThrowDrag(true); container_->SetHorizontalScrollState(false); container_->Resize(OHOS::Screen::GetInstance().GetWidth(), OHOS::Screen::GetInstance().GetHeight()); } std::list &sliceData = OHOS::NativeAbility::GetInstance().GetRecentAppsList(); dockItemInfo_.clear(); for(auto item : sliceData) { SliceInfo info = FindDockItenInfo(item); if (info.resId != 0) { dockItemInfo_.emplace_back(info); } } if (dockItemInfo_.size() == 0) { InitZeroView(); } else { OHOS::ImageCacheManager::GetInstance().LoadAllInMultiRes(DOCK_IMAGE_BIN_PATH); UITestSlipflowView(); } AddViewToRootContainer(container_); } void TjdUiAppDockView::OnStop() { dockItemInfo_.clear(); container_->Remove(slipflow_); TjdUiMemManage::DeleteChildren(container_); if (container_ != nullptr) { container_ = nullptr; } if (g_sliceInfoMap != nullptr) { g_sliceInfoMap->clear(); delete g_sliceInfoMap; g_sliceInfoMap = nullptr; } if (slipflow_ != nullptr) { TjdUiMemManage::DeleteChildren(slipflow_); delete slipflow_; slipflow_ = nullptr; } zeroGroup_ = nullptr; bg_ = nullptr; zeroLabel_ = nullptr; label_ = nullptr; slipUpNoticelabel_ = nullptr; lastIndex_ = 0; isShowBtnGrp_ = false; loadNum_ = 0; OHOS::ImageCacheManager::GetInstance().UnloadAllInMultiRes(DOCK_IMAGE_BIN_PATH); } void TjdUiAppDockView::InitZeroView() { if (container_ == nullptr) { return; } if (zeroGroup_ == nullptr) { zeroGroup_ = new OHOS::UIViewGroup(); } zeroGroup_->SetPosition(0, 0, OHOS::Screen::GetInstance().GetWidth(), OHOS::Screen::GetInstance().GetHeight()); zeroGroup_->SetTouchable(true); zeroGroup_->SetDraggable(true); zeroGroup_->SetOnDragListener(presenter_); if (zeroLabel_ == nullptr) { zeroLabel_ = new OHOS::UILabel(); } zeroLabel_->SetPosition(127, 315, 200, 50); zeroLabel_->SetTextColor(OHOS::Color::White()); zeroLabel_->SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); zeroLabel_->SetText("暂无应用"); zeroLabel_->SetFont(TJD_VECTOR_FONT_FILENAME, 32); if (bg_ == nullptr) { bg_ = new OHOS::UIImageView(); } bg_->SetPosition(139, 146, 207, 152); bg_->SetSrc(OHOS::ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_DOCK_NO_DATA, DOCK_IMAGE_BIN_PATH)); zeroGroup_->Add(bg_); zeroGroup_->Add(zeroLabel_); container_->Add(zeroGroup_); container_->Invalidate(); } void TjdUiAppDockView::UITestSlipflowView() { if (container_ == nullptr) { return; } if (slipflow_ == nullptr) { slipflow_ = new TjdUICustomSlipflowView(); } slipflow_->SetPosition(0, 0, OHOS::Screen::GetInstance().GetWidth(), OHOS::Screen::GetInstance().GetHeight()); slipflow_->SetIntercept(true); slipflow_->SetThrowDrag(true); slipflow_->SetPageSize(PAGE_WIDTH, PAGE_HEIGHT); slipflow_->SetOnSlipflowListener(this); UITestSlipflowViewInitFlow(); if (label_ == nullptr) { label_ = new OHOS::UILabelExt(); } label_->SetPosition(127, 35, 200, 50); // 127 50 200 50: label position label_->SetTextColor(OHOS::Color::White()); label_->SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); lastIndex_ = slipflow_->GetCurrentPage(); // label_->SetText(dockItemInfo_.at(lastIndex_).name); label_->SetTextId(dockItemInfo_.at(lastIndex_).nameId); label_->SetFont(TJD_VECTOR_FONT_FILENAME, 32); if (slipUpNoticelabel_ == nullptr) { slipUpNoticelabel_ = new OHOS::UILabel(); } slipUpNoticelabel_->SetPosition(127, 400, 200, 50); // 127 400 200 50: label position slipUpNoticelabel_->SetTextColor(OHOS::Color::White()); slipUpNoticelabel_->SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); slipUpNoticelabel_->SetText("继续上滑删除"); slipUpNoticelabel_->SetFont(TJD_VECTOR_FONT_FILENAME, 30); // 30 : font size slipUpNoticelabel_->SetVisible(false); slipflow_->RequestFocus(); container_->Add(slipflow_); container_->Add(label_); container_->Add(slipUpNoticelabel_); } void TjdUiAppDockView::UITestSlipflowViewInitFlow() { static_print_info("UITestSlipflowViewInitFlow"); int i = 0; for (auto it : dockItemInfo_) { OHOS::UIImageView *image = new OHOS::UIImageView(); OHOS::ImageInfo *src = OHOS::ImageCacheManager::GetInstance().LoadOneInMultiRes(it.resId, DOCK_IMAGE_BIN_PATH); // OHOS::Vector2 scale = {280.0 / src->header.width, 280.0 / src->header.height}; // image->Scale(scale, {0, 0}); // image->SetViewId(it.name); // image->SetViewIndex(it.nameId); image->SetSrc(src); image->Resize(PAGE_WIDTH, PAGE_HEIGHT); image->SetResizeMode(OHOS::UIImageView::ImageResizeMode::FILL); image->SetAutoEnable(false); OHOS::UIViewGroup *group = new OHOS::UIViewGroup(); group->SetViewIndex(i++); group->SetPosition(0, 0, PAGE_WIDTH, OHOS::Screen::GetInstance().GetHeight()); group->SetStyle(OHOS::STYLE_BACKGROUND_OPA, 0); group->SetDragParentInstead(true); group->SetTouchable(true); group->SetOnClickListener(presenter_); OHOS::UIImageView *backImage = new OHOS::UIImageView(); backImage->Resize(PAGE_WIDTH, PAGE_HEIGHT); backImage->SetResizeMode(OHOS::UIImageView::ImageResizeMode::FILL); backImage->SetAutoEnable(false); group->SetViewIndex(it.sliceId); group->Add(backImage); group->Add(image); slipflow_->Add(group); backImage->LayoutCenterOfParent(); image->LayoutCenterOfParent(); loadNum_++; } } bool TjdUiAppDockView::OnScroll(int16_t distance) { if (slipflow_->GetChildrenNumber() == 0) { label_->SetText(""); return true; } int16_t contMidX = static_cast(OHOS::Screen::GetInstance().GetWidth() / DIVISOR_TWO); int16_t minOffset = contMidX; uint8_t newCenterIndex = lastIndex_; for (uint8_t i = 0; i < slipflow_->GetChildrenNumber(); i++) { OHOS::Rect rect = slipflow_->GetViewByIndex(i)->GetOrigRect(); int16_t x = rect.GetLeft(); int16_t x1 = rect.GetRight(); int16_t xMid = static_cast(x + (x1 - x + 1) / DIVISOR_TWO); int16_t distance = MATH_ABS(xMid - contMidX); if (distance < minOffset) { newCenterIndex = i; minOffset = distance; } } if (newCenterIndex != lastIndex_) { lastIndex_ = newCenterIndex; label_->SetTextId(dockItemInfo_[lastIndex_].nameId); // label_->SetTextId(slipflow_->GetViewByIndex(lastIndex_)->GetViewIndex()); } OHOS::Rect curViewRect = slipflow_->GetViewByIndex(lastIndex_)->GetOrigRect(); int16_t centerMid = curViewRect.GetLeft() + curViewRect.GetWidth() / DIVISOR_TWO; int16_t offset = MATH_ABS(contMidX - centerMid); if (offset > curViewRect.GetWidth() / DIVISOR_TWO) { label_->SetStyle(OHOS::STYLE_TEXT_OPA, 0); } else { uint8_t alpha = (uint8_t)((1.0f - ((float)offset / (curViewRect.GetWidth() / DIVISOR_TWO))) * OHOS::OPA_OPAQUE); label_->SetStyle(OHOS::STYLE_TEXT_OPA, alpha); } return true; } void TjdUiAppDockView::OnScrollUpStart() { label_->SetVisible(false); slipUpNoticelabel_->SetVisible(true); } void TjdUiAppDockView::OnScrollUpEnd() { OnScroll(0); label_->SetVisible(true); slipUpNoticelabel_->SetVisible(false); } bool TjdUiAppDockView::OnRemove(OHOS::UIView *view) { if (view == nullptr) { return false; } if (lastIndex_ < dockItemInfo_.size()) { dockItemInfo_.erase(dockItemInfo_.begin() + lastIndex_); } int sliceId = view->GetViewIndex(); if (sliceId != 0) { OHOS::NativeAbility::GetInstance().RemoveRecentApp(sliceId); } OHOS::UIViewGroup *group = static_cast(view); OHOS::UIView *curView = group->GetChildrenHead(); OHOS::UIView *deleteView = nullptr; while (curView != nullptr) { deleteView = curView; curView = curView->GetNextSibling(); group->Remove(deleteView); delete deleteView; deleteView = nullptr; } delete group; group = nullptr; if (--loadNum_ == 0) { InitZeroView(); } return true; } void TjdUiAppDockView::OnRefreshPageOpaScale(OHOS::UIView *view, int16_t xOffset, int16_t yOffset) { OHOS::UIView *image = static_cast(view)->GetChildrenHead()->GetNextSibling(); if (xOffset < 0) { image->SetOpaScale(OHOS::OPA_OPAQUE); } else if (xOffset > slipflow_->GetPageWidth()) { image->SetOpaScale(0); } else { uint8_t alpha = (uint8_t)(OHOS::OPA_OPAQUE * (1.0f - ((float)xOffset / slipflow_->GetPageWidth()))); image->SetOpaScale(alpha); } if (yOffset > 0) { if (yOffset > (slipflow_->GetPageHeight() / DIVISOR_TWO)) { image->SetOpaScale(OHOS::OPA_OPAQUE * 0.4f); } else { uint8_t alpha = (uint8_t)(OHOS::OPA_OPAQUE * (1.0f - 0.6f * ((float)yOffset / (slipflow_->GetPageHeight() / DIVISOR_TWO)))); image->SetOpaScale(alpha); } } } } // namespace TJD