458 lines
16 KiB
C++
458 lines
16 KiB
C++
/*----------------------------------------------------------------------------
|
|
* 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<AppListItemView *>(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<float>(LinearEaseIn(0, midY, abs(offset), midY * 4)) / midY);
|
|
auto &imageView = view->GetIcon();
|
|
imageView.Scale(OHOS::Vector2<float>(scale, scale),
|
|
OHOS::Vector2<float>(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<float>(LinearEaseIn(0, midY, abs(offset), tar)) / midY);
|
|
labelView.SetStyle(OHOS::STYLE_TEXT_OPA, scale * 255);
|
|
|
|
view = static_cast<AppListItemView *>(view->GetNextSibling());
|
|
} while (view != nullptr);
|
|
}
|
|
|
|
private:
|
|
int LinearEaseIn(int start, int end, int value, int duration)
|
|
{
|
|
float t = static_cast<float>(value) / duration;
|
|
return static_cast<int>(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<E_MenuStyle>(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<E_MenuStyle>(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<E_MenuStyle>(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<E_MenuStyle>(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<AppListItemView *>(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<E_MenuStyle>(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<HexagonsItemView *> *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<WaterfallItemView *> *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<SphereItemView *> *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<GridItemView *> *viewNode = gridItemList_.Head();
|
|
while (viewNode != gridItemList_.End()) {
|
|
delete (viewNode->data_);
|
|
viewNode = viewNode->next_;
|
|
}
|
|
gridItemList_.Clear();
|
|
}
|
|
|
|
} // namespace TJD
|