/*---------------------------------------------------------------------------- * Copyright (c) TJD Technologies Co., Ltd. 2025. All rights reserved. * * Description: TjdUiAppListView.cpp * * Author: luziquan@ss-tjd.com * * Create: 2025-02-11 *--------------------------------------------------------------------------*/ #include "TjdUiAppListView.h" #include "TjdUiAppListPresenter.h" #include "TjdUiAppListView.h" #include "TjdUiImageIds.h" #include "TjdUiImageView.h" #include "TjdUiLabelView.h" #include "common/image_cache_manager.h" #include "components/ui_view_group.h" #include "hal_tick.h" #include "sys_config.h" 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 MENU_IMAGE_BIN_PATH TJD_IMAGE_PATH "/img_menu_list.bin" class TjdUiAppListView::MenuList : public OHOS::UIList { public: void ReMeasure() override { auto *view = static_cast(GetChildrenHead()); if (view == nullptr) { return; } int16_t midY = GetY() + GetHeight() / 2; int16_t y; do { y = view->GetY(); int offset = (y + (view->GetHeight() >> 1) - midY); float scale = 1.0 - (static_cast(LinearEaseIn(0, midY, abs(offset), midY * 4)) / midY); auto &imageView = view->GetIcon(); imageView.Scale(OHOS::Vector2(scale, scale), OHOS::Vector2(imageView.GetWidth() >> 1, imageView.GetHeight() >> 1)); auto &labelView = view->GetLabel(); int16_t tar = midY * 2; if (abs(offset) > tar) { offset = tar; } scale = 1.0 - (static_cast(LinearEaseIn(0, midY, abs(offset), tar)) / midY); labelView.SetStyle(OHOS::STYLE_TEXT_OPA, scale * 255); view = static_cast(view->GetNextSibling()); } while (view != nullptr); } private: int LinearEaseIn(int start, int end, int value, int duration) { float t = static_cast(value) / duration; return static_cast(start + (end - start) * t); } }; TjdUiAppListView::TjdUiAppListView() {} TjdUiAppListView::~TjdUiAppListView() { if (listAdapter_ != nullptr) { delete listAdapter_; listAdapter_ = nullptr; } if (contentList_ != nullptr) { delete contentList_; contentList_ = nullptr; } if (hexagonsList_ != nullptr) { delete hexagonsList_; hexagonsList_ = nullptr; } if (waterfallList_ != nullptr) { delete waterfallList_; waterfallList_ = nullptr; } if (sphereList_ != nullptr) { delete sphereList_; sphereList_ = nullptr; } if (gridList_ != nullptr) { delete gridList_; gridList_ = nullptr; } } void TjdUiAppListView::OnStart() { static_print_info("TjdUiAppListView::OnStart"); View::OnStart(); OHOS::ImageCacheManager::GetInstance().LoadAllInMultiRes(MENU_IMAGE_BIN_PATH); } void TjdUiAppListView::OnStop() { static_print_info("TjdUiAppListView::OnStop"); HexagonsStyleOnStop(); WaterfallStyleOnStop(); SphereStyleOnStop(); ListStyleOnStop(); GridStyleOnStop(); OHOS::FocusManager::GetInstance()->ClearFocus(); OHOS::ImageCacheManager::GetInstance().UnloadAllInMultiRes(MENU_IMAGE_BIN_PATH); } void TjdUiAppListView::RefreshAppView(void) { GetRootContainer()->RemoveAll(); E_MenuStyle style = static_cast(presenter_->GetCurrentStyle()); if (style == E_MenuStyle::MENU_STYLE_CELLUAR) { HexagonsStyleOnStart(); AddViewToRootContainer(hexagonsList_); } else if (style == E_MenuStyle::MENU_STYLE_WATERFALL) { WaterfallStyleOnStart(); AddViewToRootContainer(waterfallList_); } else if (style == E_MenuStyle::MENU_STYLE_SPHERE) { SphereStyleOnStart(); AddViewToRootContainer(sphereList_); } else if (style == E_MenuStyle::MENU_STYLE_GRID) { GridStyleOnStart(); AddViewToRootContainer(gridList_); } else { ListStyleOnStart(); AddViewToRootContainer(contentList_); } GetRootContainer()->Invalidate(); } void TjdUiAppListView::AddAppItemToList(const TjdAppItem &item) { E_MenuStyle style = static_cast(presenter_->GetCurrentStyle()); if (style == E_MenuStyle::MENU_STYLE_CELLUAR) { HexagonsItemView *itemView = new HexagonsItemView(); itemView->SetItemInfo(item); itemView->SetTouchable(true); itemView->SetOnClickListener(presenter_); hexagonsList_->Add(itemView); listHexagonsView_.PushBack(itemView); } else if (style == E_MenuStyle::MENU_STYLE_WATERFALL) { WaterfallItemView *itemView = new WaterfallItemView(); itemView->SetItemInfo(item); itemView->SetTouchable(true); itemView->SetOnClickListener(presenter_); waterfallList_->Add(itemView); waterfallItemList_.PushBack(itemView); } else if (style == E_MenuStyle::MENU_STYLE_SPHERE) { SphereItemView *itemView = new SphereItemView(); itemView->SetItemInfo(item); itemView->SetOnClickListener(presenter_); sphereList_->Add(itemView); sphereItemList_.PushBack(itemView); } else if (style == E_MenuStyle::MENU_STYLE_GRID) { GridItemView *itemView = new GridItemView(); itemView->SetItemInfo(item); itemView->SetTouchable(true); itemView->SetOnClickListener(presenter_); gridList_->Add(itemView); gridItemList_.PushBack(itemView); } else { listAdapter_->AddListItem(item); } } void TjdUiAppListView::ClearAppItemToList() { E_MenuStyle style = static_cast(presenter_->GetCurrentStyle()); if (style == E_MenuStyle::MENU_STYLE_CELLUAR) { HexagonsStyleOnStop(); } else if (style == E_MenuStyle::MENU_STYLE_WATERFALL) { WaterfallStyleOnStop(); } else if (style == E_MenuStyle::MENU_STYLE_SPHERE) { SphereStyleOnStop(); } else if (style == E_MenuStyle::MENU_STYLE_GRID) { GridStyleOnStop(); } else { listAdapter_->ClearItem(); } } void TjdUiAppListView::RefreshAppList(void) { E_MenuStyle style = static_cast(presenter_->GetCurrentStyle()); if (style == E_MenuStyle::MENU_STYLE_CELLUAR) { hexagonsList_->LayoutChildren(true); } else if (style == E_MenuStyle::MENU_STYLE_WATERFALL) { waterfallList_->LayoutChildren(true); } else if (style == E_MenuStyle::MENU_STYLE_SPHERE) { sphereList_->SetNumberOfRow(presenter_->GetListItemNum() / 3); } else if (style == E_MenuStyle::MENU_STYLE_GRID) { int16_t headY = presenter_->GetHeadItemY(); gridList_->LayoutChildren(true); gridList_->ScrollBy(0, headY); } else { if (contentList_ == nullptr) { return; } uint16_t startIndex = 0; int16_t headY = 0; if (presenter_->GetStartIndex() >= presenter_->GetListItemNum()) { startIndex = presenter_->GetListItemNum() - 1; headY = contentList_->GetHeight() / 2; } else { startIndex = presenter_->GetStartIndex(); headY = presenter_->GetHeadItemY(); } contentList_->SetAdapter(listAdapter_); if (startIndex == 0 && headY == 0) { /* 让第二项滚动到中间 */ OHOS::UIView *head = contentList_->GetChildrenHead(); while (head != nullptr && head->GetViewIndex() != 1) { head = static_cast(head->GetNextSibling()); } if (head != nullptr) { int16_t headCenterY = head->GetRect().GetTop() + (head->GetHeight() >> 1); contentList_->ScrollBy((contentList_->GetHeight() >> 1) - headCenterY); } } contentList_->ScrollTo(startIndex); contentList_->ScrollBy(headY); contentList_->RefreshList(); } } void TjdUiAppListView::ResumeWaterFallDraggable() { if (waterfallList_ != nullptr) { waterfallList_->SetTouchable(true); waterfallList_->SetDraggable(true); } } void TjdUiAppListView::ResumeFocus() { E_MenuStyle style = static_cast(presenter_->GetCurrentStyle()); if (style == E_MenuStyle::MENU_STYLE_CELLUAR) { hexagonsList_->RequestFocus(); } else if (style == E_MenuStyle::MENU_STYLE_WATERFALL) { waterfallList_->RequestFocus(); } else if (style == E_MenuStyle::MENU_STYLE_SPHERE) { sphereList_->RequestFocus(); } else if (style == E_MenuStyle::MENU_STYLE_GRID) { gridList_->RequestFocus(); } else { contentList_->RequestFocus(); } } void TjdUiAppListView::ListStyleOnStart() { if (listAdapter_ == nullptr) { listAdapter_ = new ApplistAdapter(); listAdapter_->SetItemClickListener(presenter_); } if (contentList_ == nullptr) { contentList_ = new MenuList(); } else { contentList_->RequestFocus(); return; } contentList_->SetPosition(0, 0, OHOS::Screen::GetInstance().GetWidth(), OHOS::Screen::GetInstance().GetHeight()); contentList_->SetThrowDrag(true); contentList_->SetStyle(OHOS::STYLE_BACKGROUND_OPA, OHOS::OPA_TRANSPARENT); contentList_->SetSwipeACCLevel(10); contentList_->SetDragACCLevel(10); contentList_->SetScrollBlankSize(contentList_->GetHeight() >> 1); contentList_->SetSelectPosition(contentList_->GetHeight() >> 1); contentList_->EnableAutoAlign(true); contentList_->SetAutoAlignTime(200); contentList_->EnableCrossDragBack(false); contentList_->SetElastic(true); contentList_->SetScrollStateListener(presenter_); contentList_->SetYScrollBarVisible(true); contentList_->SetOnDragListener(presenter_); contentList_->SetRotateThreshold(1); contentList_->SetRotateFactor(2); contentList_->RequestFocus(); presenter_->RefreshAppItemToList(); } void TjdUiAppListView::ListStyleOnStop() { if (contentList_) { int16_t listHeadY = contentList_->GetChildrenHead()->GetY(); int16_t listHeadIndex = contentList_->GetChildrenHead()->GetViewIndex(); presenter_->SetHeadItemY(listHeadY); presenter_->SetStartIndex(listHeadIndex); } } void TjdUiAppListView::HexagonsStyleOnStart() { if (hexagonsList_ == nullptr) { hexagonsList_ = new OHOS::UICustomHexagonsList(); } else { hexagonsList_->RequestFocus(); return; } hexagonsList_->SetPosition(0, 0, GetRootContainer()->GetWidth(), GetRootContainer()->GetHeight()); // 2, two imgDistance_ = hexagonsList_->GetWidth() * 0.25991; // 0.25991, empirical coefficient imgSize_ = hexagonsList_->GetWidth() * 0.23348; // 0.23348, empirical coefficient hexagonsList_->SetImageDistance(imgDistance_); hexagonsList_->SetImageSizeInCenter(imgSize_); int16_t blankSize = hexagonsList_->GetRelativeRect().GetWidth() > hexagonsList_->GetRelativeRect().GetHeight() ? hexagonsList_->GetRelativeRect().GetWidth() / 2 : hexagonsList_->GetRelativeRect().GetHeight() / 2; // 2, half hexagonsList_->SetScrollBlankSize(blankSize); hexagonsList_->SetReboundSize(blankSize); hexagonsList_->SetThrowDrag(true); hexagonsList_->SetOnRotateListener(presenter_); hexagonsList_->SetRotateFactor(-0.07f); hexagonsList_->RequestFocus(); presenter_->RefreshAppItemToList(); } void TjdUiAppListView::HexagonsStyleOnStop() { if (hexagonsList_ != nullptr) { hexagonsList_->RemoveAll(); } OHOS::ListNode *viewNode = listHexagonsView_.Head(); while (viewNode != listHexagonsView_.End()) { delete (viewNode->data_); viewNode = viewNode->next_; } listHexagonsView_.Clear(); } void TjdUiAppListView::WaterfallStyleOnStart() { if (waterfallList_ == nullptr) { waterfallList_ = new OHOS::UIWaterfallList(); } else { waterfallList_->RequestFocus(); return; } waterfallList_->SetPosition(0, 0, GetRootContainer()->GetWidth(), GetRootContainer()->GetHeight()); imgDistance_ = waterfallList_->GetWidth() * 0.25991; imgSize_ = waterfallList_->GetWidth() * 0.23348; waterfallList_->SetImageDistance(imgDistance_); waterfallList_->SetImageSizeInCenter(imgSize_); int16_t blankSize = waterfallList_->GetRelativeRect().GetWidth() > waterfallList_->GetRelativeRect().GetHeight() ? waterfallList_->GetRelativeRect().GetWidth() / 2 : waterfallList_->GetRelativeRect().GetHeight() / 2; // 2, half waterfallList_->SetThrowDrag(true); waterfallList_->SetReboundSize(imgDistance_ * OHOS::Sin(60)); waterfallList_->SetScrollBlankSize(0); waterfallList_->RequestFocus(); waterfallList_->SetRotateFactor(10); waterfallList_->SetOnRotateListener(presenter_); waterfallList_->SetTouchable(false); waterfallList_->SetDraggable(true); presenter_->RefreshAppItemToList(); } void TjdUiAppListView::WaterfallStyleOnStop() { if (waterfallList_ != nullptr) { waterfallList_->RemoveAll(); } OHOS::ListNode *viewNode = waterfallItemList_.Head(); while (viewNode != waterfallItemList_.End()) { delete (viewNode->data_); viewNode = viewNode->next_; } waterfallItemList_.Clear(); } void TjdUiAppListView::SphereStyleOnStart() { if (sphereList_ == nullptr) { sphereList_ = new OHOS::UISphereView(1); } else { sphereList_->RequestFocus(); return; } sphereList_->SetPosition(0, 0, OHOS::Screen::GetInstance().GetWidth(), OHOS::Screen::GetInstance().GetHeight()); sphereList_->SetThrowDrag(true); sphereList_->SetSensitivityFactor(1.5f); sphereList_->SetChildStateListener(presenter_); sphereList_->RequestFocus(); presenter_->RefreshAppItemToList(); } void TjdUiAppListView::SphereStyleOnStop() { if (sphereList_ != nullptr) { sphereList_->RemoveAll(); } OHOS::ListNode *viewNode = sphereItemList_.Head(); while (viewNode != sphereItemList_.End()) { delete (viewNode->data_); viewNode = viewNode->next_; } sphereItemList_.Clear(); } void TjdUiAppListView::GridStyleOnStart() { if (gridList_ == nullptr) { gridList_ = new TjdUIGridList(); } else { gridList_->RequestFocus(); return; } gridList_->SetPosition(0, 0, OHOS::Screen::GetInstance().GetWidth(), OHOS::Screen::GetInstance().GetHeight()); gridList_->SetReboundSize(OHOS::Screen::GetInstance().GetWidth() / 2); gridList_->RequestFocus(); gridList_->SetThrowDrag(true); gridList_->SetYScrollBarVisible(true); gridList_->SetSwipeACCLevel(10); gridList_->SetDragACCLevel(10); gridList_->SetOnDragListener(presenter_); presenter_->RefreshAppItemToList(); } void TjdUiAppListView::GridStyleOnStop() { if (gridList_ != nullptr) { int16_t listHeadY = gridList_->GetChildrenHead()->GetRect().GetTop() - 66; presenter_->SetHeadItemY(listHeadY); gridList_->RemoveAll(); } OHOS::ListNode *viewNode = gridItemList_.Head(); while (viewNode != gridItemList_.End()) { delete (viewNode->data_); viewNode = viewNode->next_; } gridItemList_.Clear(); } } // namespace TJD