[Cocos2d-x] テキストフィールドを使用する - CCTextFieldTTF

cocos2d-x

Cocos2d-x では テキストフィールドを利用するためのクラス CCTextFieldTTF が用意されている。

サンプルの TextInputTest のコードを見れば使い方はだいたい分かるはず。

下の動画は TextInputTest の動画

[cocos2d-x] CCTextFieldTTF with customizable effects & multiplatform support - YouTube

以下、サンプルコードについてのメモ

KeyboardNotificationLayer クラス

CCIMEDelegate と CCLayer を継承しており、画面のタッチ時にキーボードを呼び出す機能を持っているクラス。

CCIMEDelegate は 以下の仮想関数を持っている

  • keyboardDidHide(CCIMEKeyboardNotificationInfo &info);
  • keyboardDidShow(CCIMEKeyboardNotificationInfo &info);
  • keyboardWillHide(CCIMEKeyboardNotificationInfo &info);
  • keyboardWillShow(CCIMEKeyboardNotificationInfo &info);

KeyboardNotificationLayer クラスで使われているのはkeyboardWillShowのみ。

void KeyboardNotificationLayer::keyboardWillShow(CCIMEKeyboardNotificationInfo& info)
{
    // info.end は ソフトウェアキーボードの表示後の位置とサイズ - ようするに CCRect 
    CCLOG("TextInputTest:keyboardWillShowAt(origin:%f,%f, size:%f,%f)",
        info.end.origin.x, info.end.origin.y, info.end.size.width, info.end.size.height);

    if (! m_pTrackNode)
    {
        return;
    }

    CCRect rectTracked = getRect(m_pTrackNode);
    CCLOG("TextInputTest:trackingNodeAt(origin:%f,%f, size:%f,%f)",
        rectTracked.origin.x, rectTracked.origin.y, rectTracked.size.width, rectTracked.size.height);

    // if the keyboard area doesn't intersect with the tracking node area, nothing need to do.
    // 上の文章を訳すと「テキストフィールドとキーボードがかぶらなければ特に処理する必要はないよ」
    if (! CCRect::CCRectIntersectsRect(rectTracked, info.end))
    {
        return;
    }

    // assume keyboard at the bottom of screen, calculate the vertical adjustment.
    // 位置が被っていた場合はテキストフィールドが見えなくなってしまうためマズイ。
    // だから以下のコードで位置を調整している
    // ※このサンプルコードは キーボードを閉じた後に、テキストフィールドの位置を戻す機能はない。
    float adjustVert = CCRect::CCRectGetMaxY(info.end) - CCRect::CCRectGetMinY(rectTracked);
    CCLOG("TextInputTest:needAdjustVerticalPosition(%f)", adjustVert);

    // move all the children node of KeyboardNotificationLayer
    CCArray * children = getChildren();
    CCNode * node = 0;
    int count = children->count();
    CCPoint pos;
    for (int i = 0; i < count; ++i)
    {
        node = (CCNode*)children->objectAtIndex(i);
        pos = node->getPosition();
        pos.y += adjustVert;
        node->setPosition(pos);
    }
}

TextFieldDefaultTest クラス

KeyboradNotificationLayer の純粋仮想関数 vonClickTrackNode(bool bClicked) が実装されている。このメソッドはテキストフィールドがタッチされたときに KeyboardNotificationLayer#ccTouchesEnd から呼び出される。

TextFieldActionTestクラス

このクラスは KeyboardNotificationLayer と CCTextFiedlDelegate を継承している。CCTextFieldDelegateはテキストフィールドのイベント時にコールされる関数が定義されている。

  • virtual bool onTextFieldAttachWithIME(cocos2d::CCTextFieldTTF *sender); : IMEをアタッチした時(ソフトフェアキーボードが呼び出されるとき)に実行される
  • virtual bool onTextFieldDetachWithIME(cocos2d::CCTextFieldTTF *sender); : 上の逆
  • virtual bool onTextFieldDeleteBackward(cocos2d::CCTextFieldTTF *sender, const char *delText, int nLen); : 文字を一文字消した時(バックスペース)
  • virtual bool onTextFieldInsertText(cocos2d::CCTextFieldTTF *sender, const char *text, int nLen); : キーボードなどから文字を入力した時

これの中身をかえることで動画のように入力時にアニメーションをさせたりとか、文字列が一定の長さに達したら折り返したりとかの処理を書き込める。

まぁそういうことで

CCIMEDelegate を実装したクラスと、CCTextFieldDelegate を実装したクラスに処理をデリゲートすればいいですよ、という感じですね。

テキストフィールドに表示されている文字は CCLabelTTF が使われているけど、ビットマップフォントは使えないんだろか。

Share
関連記事