mcu_hi3321_watch/tjd/ui/app/applist/TjdUiAppListView.cpp
2025-05-26 20:15:20 +08:00

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