UI Nodesを試す TableView編



cocos2d-x v3系のTableViewを試したので、メモ。
今回は表示する内容をVectorで持つことにしました。

完成イメージ
![tableview_v3.png](https://qiita-image-store.s3.amazonaws.com/0/20511/bc4d9f36-1719-63e8-ce42-fa619f5e9a39.png "tableview_v3.png")




下記にお試しコードを記載

```HelloWorldScene.h

#include "cocos2d.h"
#include "extensions/cocos-ext.h"

USING_NS_CC;
USING_NS_CC_EXT;

class HelloWorld : public Layer,
                   public TableViewDataSource,
                   public TableViewDelegate {
private:
    std::vector<std::string> _contents;
    
public:
    static cocos2d::Scene* createScene();
    virtual bool init();

    // TableView Delegate
    virtual Size cellSizeForTable(TableView* table);
    virtual TableViewCell* tableCellAtIndex(TableView* table, ssize_t idx);
    virtual ssize_t numberOfCellsInTableView(TableView* table);
    virtual void tableCellTouched(TableView* table, TableViewCell* cell);

    CREATE_FUNC(HelloWorld);
};

```

本来であれば、headerファイルでUSING_NS_xxx;を指定するのは辞めたほうがいいですね。


```HelloWorldScene.cpp

bool HelloWorld::init()
{
    if (!Layer::init()) {
        return false;
    }

    Size visibleSize = Director::getInstance()->getVisibleSize();

    // Data
    _contents = {
        "つば九郎",
        "つばみ",
        "トルクーヤ",
    };

    // TableView
    TableView* tableView = TableView::create(this, Size(visibleSize.width, visibleSize.height));
    tableView->setDirection(TableView::Direction::VERTICAL);
    tableView->setVerticalFillOrder(TableView::VerticalFillOrder::TOP_DOWN);
    tableView->setAnchorPoint(Vec2::ZERO);
    tableView->setPosition(Vec2::ZERO);
    tableView->setDelegate(this);
    this->addChild(tableView);
    tableView->reloadData();

    return true;
}

//---------------------------------------------------------------
#pragma mark - Table View Delegate
//---------------------------------------------------------------

ssize_t HelloWorld::numberOfCellsInTableView(TableView* table)
{
    return _contents.size();
}

Size HelloWorld::cellSizeForTable(TableView* table)
{
    return Size(table->getContentSize().width, 100);
}

void HelloWorld::tableCellTouched(TableView* table, TableViewCell* cell)
{
    // log("cellがタップされました");
}

TableViewCell* HelloWorld::tableCellAtIndex(TableView* table, ssize_t idx)
{
    TableViewCell* cell = table->dequeueCell();
    cell = new TableViewCell();
    cell->autorelease();

    // セルの背景
    auto bg = Sprite::create();
    bg->setAnchorPoint(Vec2(0, 0));
    bg->setTextureRect(Rect(0, 0, table->getContentSize().width, 99));
    bg->setColor(Color3B(230, 230, 230));
    cell->addChild(bg);

    // テキスト
    auto text = StringUtils::format("%ld : %s", idx, _contents[idx].c_str());
    auto label = Label::createWithSystemFont(text.c_str(), "fonts/Marker Felt.ttf", 30);
    label->setAnchorPoint(Vec2::ZERO);
    label->setPosition(Vec2(50, 30));
    label->setColor(Color3B(100, 100, 100));
    cell->addChild(label);

    return cell;
}


```

特別なケースでなければ、TableViewCellのwidthはTableViewのwidthに合わせて良いかと思います。


### 主なTable設定

#### setDirection : テーブルの方向指定

```
enum class Direction
{
    NONE = -1,      // 縦横両方向 （ バウンスが効かない ) 
    HORIZONTAL = 0, // 横方向
    VERTICAL,       // 縦方向
    BOTH            // 縦横両方向
};
```


#### setVerticalFillOrder : セルの表示順指定

```
enum class VerticalFillOrder
{
    TOP_DOWN, // 上から下
    BOTTOM_UP // 下から上
};
```





### 所感

モリモリなCellを用意するのであれば、TableViewCellのサブクラスを用意したほうがいいですね。
少し動作感がチープですが、実装も簡単なので満足？です。


参考 : http://www.cocos2d-x.org/reference/native-cpp/V3.6/d2/d4b/classcocos2d_1_1extension_1_1_table_view.html