Last active
August 31, 2016 03:31
-
-
Save hsienwei/3d6937d893e94cbc64a0812477376f1e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TableViewUtilEx<FrameHeros> m_TableUtil; | |
m_TableUtil.m_ScrollView = (ScrollView*)pObj; | |
m_TableUtil.m_CellWidget = dynamic_cast<Widget*>(_node->getChildByName("pal_hero"));; | |
m_TableUtil.m_PaddingX = 1; | |
m_TableUtil.m_PaddingY = 1; | |
m_TableUtil.m_CellSpaceX = 1; | |
m_TableUtil.m_CellSpaceY = 1; | |
m_TableUtil.m_Delegate = this; | |
m_TableUtil.m_Direction = m_TableUtil.VERTICAL; | |
m_TableUtil.calculateBaseCount(); | |
m_TableUtil.init(); | |
void FrameHeros::update( float delta ) | |
{ | |
m_TableUtil.ResetItem(); | |
} | |
int FrameHeros::GetItemCount() | |
{ | |
return nowitem; | |
} | |
bool FrameHeros::OnItemShow(Node *node, int idx) | |
{ | |
CreateUnit(dynamic_cast<Widget*>(node), idx); | |
return false; // true: 繼續加下一個, false: 停止加下一個, 下一個frame再加. | |
} | |
void FrameHeros::update( float delta ) | |
{ | |
m_TableUtil.ResetItem(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*class TableDelegate | |
{ | |
public: | |
int GetItemCount(){return 0;} | |
bool OnItemShow( Node *Item, int Index){}; | |
};*/ | |
template<class TableDelegateT> | |
class TableViewUtilEx | |
{ | |
public: | |
enum Direction | |
{ | |
VERTICAL = 0, | |
HORIZONTAL, | |
}; | |
TableViewUtilEx() | |
: m_ScrollView(nullptr) | |
, m_CellWidget(nullptr) | |
, m_CellPath() | |
, m_BaseCount(0) | |
, m_PaddingX(0) | |
, m_PaddingY(0) | |
, m_CellSpaceX(0) | |
, m_CellSpaceY(0) | |
, m_Direction(VERTICAL) | |
, m_Delegate( nullptr ) | |
, m_RangeMin(0) | |
, m_RangeMax(-1) | |
, m_ItemSizeWidth(-1) | |
, m_ItemSizeHeight(-1) | |
{ | |
m_FreeItemNode.clear(); | |
} | |
void init() | |
{ | |
while(m_ScrollView->getChildrenCount() > 0) | |
{ | |
Node* Child = m_ScrollView->getChildren().at(0); | |
Child->setTag(-1); | |
m_FreeItemNode.pushBack(Child); | |
Child->removeFromParent(); | |
} | |
if(m_Delegate == nullptr) return; | |
m_ScrollView->jumpToPercentVertical(0); | |
calculateBaseCount(); | |
ScrollViewContentFit(m_Delegate->GetItemCount()); | |
ResetItem(); | |
} | |
void Clear() | |
{ | |
if(NULL != m_CellWidget) | |
{ | |
m_CellWidget = NULL; | |
} | |
if(NULL != m_ScrollView) | |
{ | |
m_ScrollView->removeAllChildren(); | |
} | |
m_FreeItemNode.clear(); | |
} | |
cocos2d::Size GetCellSize() | |
{ | |
if( m_CellWidget != nullptr ) | |
{ | |
return m_CellWidget->getContentSize(); | |
} | |
return cocos2d::Size(m_ItemSizeWidth, m_ItemSizeHeight); | |
} | |
void GetScroolViewRange( int &Start, int &End ) | |
{ | |
cocos2d::Size CellSize = GetCellSize(); | |
cocos2d::ui::Layout *Layout = m_ScrollView->getInnerContainer(); | |
Vec2 LayoutPos = Layout->getPosition(); | |
if(m_Direction == VERTICAL ) | |
{ | |
float UpY = LayoutPos.y - m_ScrollView->getContentSize().height + m_ScrollView->getInnerContainerSize().height; | |
int UpRow = (UpY - m_PaddingY) / (CellSize.height + m_CellSpaceY ); | |
int StartIdx = UpRow * m_BaseCount; | |
float DownY = LayoutPos.y + m_ScrollView->getInnerContainerSize().height ; | |
int DownRow = (DownY - m_PaddingY) / (CellSize.height + m_CellSpaceY ); | |
int EndIdx = (DownRow + 1) * m_BaseCount - 1; | |
// cocos2d::log("%f:%d:%d", LayoutPos.y, UpRow, DownRow); | |
Start = StartIdx; | |
End = EndIdx; | |
} | |
else | |
{ | |
float LeftX = -LayoutPos.x; | |
int LeftColumn = (LeftX - m_PaddingX) / (CellSize.width + m_CellSpaceX ); | |
int StartIdx = LeftColumn * m_BaseCount; | |
float RightX = -LayoutPos.x + m_ScrollView->getContentSize().width; | |
int RightColumn = (RightX - m_PaddingX) / (CellSize.width + m_CellSpaceX ); | |
int EndIdx = (RightColumn + 1) * m_BaseCount - 1; | |
// cocos2d::log("%f:%d:%d", LayoutPos.x, LeftColumn, RightColumn); | |
Start = StartIdx; | |
End = EndIdx; | |
} | |
if( Start < 0) Start = 0; | |
if( End < 0) End = 0; | |
} | |
void ResetItem() | |
{ | |
if(m_Delegate == nullptr) return; | |
if(m_CellWidget == nullptr) return; | |
int StartIdx, EndIdx; | |
GetScroolViewRange( StartIdx, EndIdx ); | |
int WorkStartIdx = min(m_RangeMin, StartIdx); | |
int WorkEndIdx = max(m_RangeMax, EndIdx); | |
int ListCount = m_Delegate->GetItemCount(); | |
if(ListCount == 0) | |
{ | |
return; | |
} | |
bool AddFlag = true; | |
for( int i = WorkStartIdx; i<= WorkEndIdx; ++i) | |
{ | |
Vec2 ItemPos = GetCellPosition(i); | |
Node *Child = m_ScrollView->getChildByTag(i); | |
if( i <= EndIdx && i >= StartIdx && i < ListCount) | |
{ | |
if( !AddFlag ) continue; | |
if( Child ) | |
{ | |
Child->setPosition( ItemPos ); | |
//AddFlag = m_Delegate->OnItemShow(Child, i); | |
} | |
else | |
{ | |
Node *FreeNode = GetFreeItem(); | |
if(FreeNode != nullptr) | |
{ | |
Vec2 ItemPos = GetCellPosition(i); | |
m_ScrollView->addChild(FreeNode); | |
m_FreeItemNode.popBack(); | |
FreeNode->setPosition( ItemPos ); | |
FreeNode->setTag(i); | |
AddFlag = m_Delegate->OnItemShow(FreeNode, i); | |
} | |
} | |
} | |
else | |
{ | |
if( Child ) | |
{ | |
m_FreeItemNode.pushBack(Child); | |
Child->setTag(-1); | |
Child->removeFromParent(); | |
} | |
} | |
} | |
m_RangeMin = StartIdx; | |
m_RangeMax = EndIdx; | |
// cocos2d::log("free count:%d || scrollview child count: %d", m_FreeItemNode.size(), m_ScrollView->getChildrenCount()); | |
} | |
Node* GetFreeItem() | |
{ | |
Node* FreeItem = nullptr; | |
if(m_FreeItemNode.size() == 0) | |
{ | |
if( m_CellWidget == nullptr ) | |
{ | |
m_FreeItemNode.pushBack( CSLoader::createNode(m_CellPath) ); | |
} | |
else | |
{ | |
m_FreeItemNode.pushBack(m_CellWidget->clone()); | |
} | |
} | |
FreeItem = m_FreeItemNode.back(); | |
return FreeItem; | |
} | |
void calculateBaseCount() | |
{ | |
cocos2d::Size scrollSize = m_ScrollView->getContentSize(); | |
cocos2d::Size cellSize = GetCellSize(); | |
m_BaseCount = 1; | |
if(m_Direction == VERTICAL ) | |
{ | |
float calculateWidth = scrollSize.width - m_PaddingX *2 ; | |
m_BaseCount = calculateWidth / (cellSize.width); | |
if(1 < m_BaseCount) | |
{ | |
m_CellSpaceX = (scrollSize.width - m_PaddingX *2 - cellSize.width * m_BaseCount) / (m_BaseCount - 1); | |
} | |
else | |
{ | |
m_CellSpaceX = scrollSize.width - m_PaddingX *2 - cellSize.width * m_BaseCount; | |
} | |
} | |
else | |
{ | |
float calculateHeight = scrollSize.height - m_PaddingY *2 ; | |
m_BaseCount = calculateHeight / (cellSize.height); | |
if(1 < m_BaseCount) | |
{ | |
m_CellSpaceY = (scrollSize.height - m_PaddingY *2 - cellSize.height * m_BaseCount) / (m_BaseCount - 1); | |
} | |
else | |
{ | |
m_CellSpaceY = scrollSize.height - m_PaddingY *2 - cellSize.height * m_BaseCount; | |
} | |
} | |
} | |
void ScrollViewContentFit(int cellCount) | |
{ | |
cocos2d::Size cellSize = GetCellSize(); | |
if(m_Direction == VERTICAL ) | |
{ | |
int row = cellCount / m_BaseCount ; | |
if( cellCount % m_BaseCount > 0) | |
{ | |
row++; | |
} | |
float scrollViewExpendHeight = m_PaddingY * 2 + cellSize.height * row + m_CellSpaceY * (row -1); | |
m_ScrollView->setInnerContainerSize(cocos2d::Size(m_ScrollView->getContentSize().width, scrollViewExpendHeight)); | |
} | |
else | |
{ | |
int column = cellCount / m_BaseCount; | |
if( cellCount % m_BaseCount > 0) | |
{ | |
column++; | |
} | |
float scrollViewExpendWidth = m_PaddingX * 2 + cellSize.width * column + m_CellSpaceX * (column -1); | |
m_ScrollView->setInnerContainerSize(cocos2d::Size(scrollViewExpendWidth, m_ScrollView->getContentSize().height)); | |
} | |
} | |
Vec2 GetCellPosition(int idx) | |
{ | |
cocos2d::Size cellSize = GetCellSize(); | |
Vec2 rtn; | |
if(0 >= m_BaseCount) | |
{ | |
return rtn; | |
} | |
if(m_Direction == VERTICAL ) | |
{ | |
rtn.x = idx % m_BaseCount * cellSize.width + (idx % m_BaseCount) * m_CellSpaceX + m_PaddingX + cellSize.width/2; | |
rtn.y = m_ScrollView->getInnerContainerSize().height - idx / m_BaseCount * cellSize.height - ((idx / m_BaseCount)) * m_CellSpaceY - m_PaddingY -cellSize.height/2; | |
} | |
else | |
{ | |
rtn.y = m_ScrollView->getContentSize().height - idx % m_BaseCount * cellSize.height - ((idx % m_BaseCount) - 1) * m_CellSpaceY - m_PaddingY - cellSize.height/2; | |
rtn.x = idx / m_BaseCount * cellSize.width + (idx / m_BaseCount) * m_CellSpaceX + m_PaddingX +cellSize.width/2; | |
} | |
return rtn; | |
} | |
TableDelegateT *m_Delegate; | |
cocos2d::ui::ScrollView *m_ScrollView; | |
cocos2d::ui::Widget *m_CellWidget; | |
int m_BaseCount; | |
float m_PaddingX; | |
float m_PaddingY; | |
float m_CellSpaceX; | |
float m_CellSpaceY; | |
int m_Direction; | |
int m_RangeMin, m_RangeMax; | |
float m_ItemSizeWidth, m_ItemSizeHeight; | |
std::string m_CellPath; | |
cocos2d::Vector<Node*> m_FreeItemNode; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment