cococos 2 d-x CCTable View動的挿入削除要素bug修正およびアニメーション表現


cococos 2 d-x CCTable View動的挿入削除要素にバグがあり、異常を示す.また、私が使っている間にアニメーション表現(UItableViewのようにreloadWithAnimation)を追加したいと思っています.最初は複雑だと思っていましたが、テスト後に修正が必要なところは多くないことに気づきました.コードは個人のニーズを満たすだけで、インタフェースがきれいではないと思ったら、自分で修正することができます.
void insertCellAtIndex(unsigned int idx, float insertDelayTime);//  delaytime , 
int indexFromPoint(int x, int y);
CCPoint pointFromIndex(int index);

void delayInsertCell();

int m_indexToInsert;		//  

cppファイルの変更:
void CCTableView::insertCellAtIndex(unsigned  int idx, float insertDelayTime)
{
    if (idx == CC_INVALID_INDEX)
    {
        return;
    }

    unsigned int uCountOfItems = m_pDataSource->numberOfCellsInTableView(this);
    if (0 == uCountOfItems || idx > uCountOfItems-1)
    {
        return;
    }

    CCTableViewCell* cell = NULL;
    int newIdx = 0;

    cell = (CCTableViewCell*)m_pCellsUsed->objectWithObjectID(idx);
	m_pIndices->clear();
    if (cell)
    {
        newIdx = m_pCellsUsed->indexOfSortedObject(cell);

		for (int i = 0; i < (int)newIdx; ++i) {
			cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(i);
			m_pIndices->insert(cell->getIdx());
		}

        for (unsigned int i=newIdx; icount(); i++)
        {
            cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(i);
			int ni = cell->getIdx()+1;
            this->_setIndexForCell(ni, cell, true);
			m_pIndices->insert(ni);
        }
    }

 //   [m_pIndices shiftIndexesStartingAtIndex:idx by:1];
	if (insertDelayTime > 0) {
		m_indexToInsert = idx;
		CCDelayTime* delay = CCDelayTime::create(0.2f);
		CCCallFunc* call = CCCallFunc::create(this, callfunc_selector(CCTableView::delayInsertCell));
		CCSequence* seq = CCSequence::createWithTwoActions(delay, call);
		this->runAction(seq);
	} else {
		//insert a new cell
		cell = m_pDataSource->tableCellAtIndex(this, idx);
		this->_setIndexForCell(idx, cell, false);
		this->_addCellIfNecessary(cell);

		this->_updateCellPositions();
		this->_updateContentSize();
	}
}

void CCTableView::delayInsertCell()
{
	CCTableViewCell* cell = m_pDataSource->tableCellAtIndex(this, m_indexToInsert);
	this->_setIndexForCell(m_indexToInsert, cell, false);
	this->_addCellIfNecessary(cell);

	this->_updateCellPositions();
	this->_updateContentSize();
}

void CCTableView::removeCellAtIndex(unsigned int idx)
{
    if (idx == CC_INVALID_INDEX)
    {
        return;
    }

    unsigned int uCountOfItems = m_pDataSource->numberOfCellsInTableView(this);
    if (0 == uCountOfItems || idx > uCountOfItems-1)
    {
        return;
    }

    unsigned int newIdx = 0;

    CCTableViewCell* cell = this->cellAtIndex(idx);
    if (!cell)
    {
        return;
    }

    newIdx = m_pCellsUsed->indexOfSortedObject(cell);

    //remove first
    this->_moveCellOutOfSight(cell);

   
    this->_updateCellPositions();
//    [m_pIndices shiftIndexesStartingAtIndex:idx+1 by:-1];

	//  indices 
	m_pIndices->clear();
	for (int i = 0; i < (int)newIdx; ++i) {
		cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(i);
		m_pIndices->insert(cell->getIdx());
	}

    for (int i=(int)m_pCellsUsed->count()-1; i >= (int)newIdx; --i)
    {
        cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(i);
		int ni = cell->getIdx()-1;
        this->_setIndexForCell(ni, cell, true);
		m_pIndices->insert(ni);
    }

	//  
	if (m_pCellsUsed->count() > 0) {
		cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(m_pCellsUsed->count() - 1);
		int index = cell->getIdx() + 1;
		if (index < (int)m_pDataSource->numberOfCellsInTableView(this)) {
			//  , 
			this->updateCellAtIndex(index);

			//  , cell
			cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(m_pCellsUsed->count() - 1);
			CCPoint dst = cell->getPosition();
			cell->setPositionX(dst.x + m_vCellsPositions[index] - m_vCellsPositions[index - 1]);
			CCMoveTo* moveTo = CCMoveTo::create(0.2f, dst);
			cell->runAction(moveTo);
		}
	}
}

void CCTableView::_setIndexForCell(unsigned int index, CCTableViewCell *cell, bool animate)
{
	if (!cell) {
		return;
	}
    cell->setAnchorPoint(ccp(0.0f, 0.0f));
	CCPoint pt = this->_offsetFromIndex(index);
	if (animate) {
		CCMoveTo* moveTo = CCMoveTo::create(0.2f, pt);
		cell->runAction(moveTo);
	} else {
		cell->setPosition(pt);
	}

    cell->setIdx(index);
}

int CCTableView::indexFromPoint(int x, int y)
{
	CCPoint offset = this->convertToNodeSpace(ccp(x, y));
	CCPoint of2 = getContentOffset();
	offset.x -= of2.x;
	offset.y -= of2.y;
	int index =  _indexFromOffset(offset);
	CCPoint roffset = _offsetFromIndex(index);
	CCSize size = m_pDataSource->cellSizeForTable(this);
	if (offset.x - roffset.x >= size.width / 2) {
		++index;
	}

	if (index < 0) {
		index = 0;
	}

	int amount = m_pDataSource->numberOfCellsInTableView(this);
	if (index > amount) {
		index = amount;
	}
	return index;
}

CCPoint CCTableView::pointFromIndex(int index)
{
	CCPoint offset = __offsetFromIndex(index);
	CCPoint of2 = getContentOffset();
	offset.x += of2.x;
	offset.y += of2.y;

	CCPoint pt = convertToWorldSpace(offset);
	pt = getParent()->convertToNodeSpace(pt);
	return pt;
}

簡単な説明:
1、削除要素を挿入する時、正しい設定がないためm_pIndicesは様々な表現異常を引き起こした.cococos 2 d-iphoneのコードは正しいので、コードの中の注釈の1つに注意してください.しかし移植时にサボって処理していないし、ずっと処理していない...
2、アニメーションを追加するのは簡単です.setPositionの場合、CCMoveToのactionを使います.挿入時に外部アニメーション(ドラッグした要素など)と合わせるために遅延アニメーションを追加します.そうしないと、挿入した要素がすぐに表示され、うまく表現されません.
3、pointFromIndex indexFromPointの2つの関数は、外部に座標計算をエクスポートするためにも使用されます(ドラッグした要素がどの位置にアニメーションを移動して消えるべきかなど).