diff --git a/cocos2dx/include/CCTextFieldTTF.h b/cocos2dx/include/CCTextFieldTTF.h index 2d54455828..6641a59aae 100644 --- a/cocos2dx/include/CCTextFieldTTF.h +++ b/cocos2dx/include/CCTextFieldTTF.h @@ -39,7 +39,7 @@ public: /** @brief If the sender doesn't want to attach with IME, return true; */ - bool onTextFieldAttachWithIME(CCTextFieldTTF * sender) + virtual bool onTextFieldAttachWithIME(CCTextFieldTTF * sender) { return false; } @@ -47,7 +47,7 @@ public: /** @brief If the sender doesn't want to detach with IME, return true; */ - bool onTextFieldDetachWithIME(CCTextFieldTTF * sender) + virtual bool onTextFieldDetachWithIME(CCTextFieldTTF * sender) { return false; } @@ -55,7 +55,7 @@ public: /** @brief If the sender doesn't want to insert the text, return true; */ - bool onTextFieldInsertText(CCTextFieldTTF * sender, const char * text, int nLen) + virtual bool onTextFieldInsertText(CCTextFieldTTF * sender, const char * text, int nLen) { return false; } @@ -63,7 +63,7 @@ public: /** @brief If the sender doesn't want to delete the delText, return true; */ - bool onTextFieldDeleteBackward(CCTextFieldTTF * sender, const char * delText, int nLen) + virtual bool onTextFieldDeleteBackward(CCTextFieldTTF * sender, const char * delText, int nLen) { return false; } @@ -71,7 +71,7 @@ public: /** @brief If doesn't want draw sender as default, return true. */ - bool onDraw(CCTextFieldTTF * sender) + virtual bool onDraw(CCTextFieldTTF * sender) { return false; } diff --git a/cocos2dx/text_input_node/CCIMEDispatcher.cpp b/cocos2dx/text_input_node/CCIMEDispatcher.cpp index 1e21b4dad4..3fc914f636 100644 --- a/cocos2dx/text_input_node/CCIMEDispatcher.cpp +++ b/cocos2dx/text_input_node/CCIMEDispatcher.cpp @@ -153,7 +153,16 @@ bool CCIMEDispatcher::attachDelegateWithIME(CCIMEDelegate * pDelegate) CCIMEDelegate * pOldDelegate = m_pImpl->m_DelegateWithIme; m_pImpl->m_DelegateWithIme = 0; pOldDelegate->didDetachWithIME(); + + m_pImpl->m_DelegateWithIme = *iter; + pDelegate->didAttachWithIME(); + bRet = true; + break; } + + // havn't delegate attached with IME yet + CC_BREAK_IF(! pDelegate->canAttachWithIME()); + m_pImpl->m_DelegateWithIme = *iter; pDelegate->didAttachWithIME(); bRet = true; diff --git a/cocos2dx/text_input_node/CCTextFieldTTF.cpp b/cocos2dx/text_input_node/CCTextFieldTTF.cpp index e4b261102d..0d74da4f30 100644 --- a/cocos2dx/text_input_node/CCTextFieldTTF.cpp +++ b/cocos2dx/text_input_node/CCTextFieldTTF.cpp @@ -165,7 +165,7 @@ bool CCTextFieldTTF::canAttachWithIME() bool CCTextFieldTTF::canDetachWithIME() { - return (m_pDelegate) ? (! m_pDelegate->onTextFieldAttachWithIME(this)) : true; + return (m_pDelegate) ? (! m_pDelegate->onTextFieldDetachWithIME(this)) : true; } void CCTextFieldTTF::insertText(const char * text, int len) diff --git a/tests/tests/TextInputTest/TextInputTest.cpp b/tests/tests/TextInputTest/TextInputTest.cpp index 96f9bca17e..fb53b3e957 100644 --- a/tests/tests/TextInputTest/TextInputTest.cpp +++ b/tests/tests/TextInputTest/TextInputTest.cpp @@ -54,7 +54,7 @@ CCLayer* backTextInputTest() return restartTextInputTest(); } -CCRect getRect(CCNode * pNode) +static CCRect getRect(CCNode * pNode) { CCRect rc; rc.origin = pNode->getPosition(); @@ -128,7 +128,7 @@ void TextInputTest::onEnter() addChild(l, 1); l->setPosition(ccp(s.width/2, s.height-80)); } - +#if 0 CCMenuItemImage *item1 = CCMenuItemImage::itemFromNormalImage("Images/b1.png", "Images/b2.png", this, menu_selector(TextInputTest::backCallback)); CCMenuItemImage *item2 = CCMenuItemImage::itemFromNormalImage("Images/r1.png","Images/r2.png", this, menu_selector(TextInputTest::restartCallback) ); CCMenuItemImage *item3 = CCMenuItemImage::itemFromNormalImage("Images/f1.png", "Images/f2.png", this, menu_selector(TextInputTest::nextCallback) ); @@ -140,6 +140,7 @@ void TextInputTest::onEnter() item3->setPosition(ccp( s.width/2 + 100,30)); addChild(menu, 1); +#endif } void TextInputTest::onExit() @@ -212,31 +213,53 @@ void KeyboardNotificationLayer::keyboardWillShow(CCIMEKeyboardNotificationInfo& // implement TextFieldTTFTest ////////////////////////////////////////////////////////////////////////// -TextFieldTTFTest::TextFieldTTFTest() -: m_nSelected(-1) -{ - CCSize s = CCDirector::sharedDirector()->getWinSize(); - - m_pTextField[0] = CCTextFieldTTF::textFieldWithPlaceHolder("", - CCSizeMake(240, 28), - CCTextAlignmentCenter, - "Thonburi", - 24); - addChild(m_pTextField[0]); - m_pTextField[0]->setPosition(ccp(s.width/2, s.height/2 + 16)); - - m_pTextField[1] = CCTextFieldTTF::textFieldWithPlaceHolder("", - "Thonburi", - 24); - addChild(m_pTextField[1]); - m_pTextField[1]->setPosition(ccp(s.width/2, s.height/2 - 16)); -} +#define FONT_NAME "Thonburi" +#define FONT_SIZE 24 std::string TextFieldTTFTest::subtitle() { return "CCTextFieldTTF test"; } +void TextFieldTTFTest::onEnter() +{ + KeyboardNotificationLayer::onEnter(); + + m_nSelected = -1; + m_nCharLimit = 10; + + m_pTextFieldAction = CCRepeatForever::actionWithAction( + (CCActionInterval*)CCSequence::actions( + CCFadeOut::actionWithDuration(0.25), + CCFadeIn::actionWithDuration(0.25), + 0 + )); + m_pTextFieldAction->retain(); + m_bAction = false; + + // add CCTextFieldTTF + CCSize s = CCDirector::sharedDirector()->getWinSize(); + + m_pTextField[0] = CCTextFieldTTF::textFieldWithPlaceHolder("", + FONT_NAME, + FONT_SIZE); + addChild(m_pTextField[0]); + + m_pTextField[0]->setDelegate(this); + m_pTextField[0]->setPosition(ccp(s.width/2, s.height/2 + 16)); + + m_pTextField[1] = CCTextFieldTTF::textFieldWithPlaceHolder("", + FONT_NAME, + FONT_SIZE); + addChild(m_pTextField[1]); + m_pTextField[1]->setPosition(ccp(s.width/2, s.height/2 - 16)); +} + +void TextFieldTTFTest::onExit() +{ + m_pTextFieldAction->release(); +} + bool TextFieldTTFTest::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) { m_beginPos = pTouch->locationInView(pTouch->view()); @@ -294,6 +317,121 @@ void TextFieldTTFTest::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) } } +// CCTextFieldDelegate protocol +bool TextFieldTTFTest::onTextFieldAttachWithIME(CCTextFieldTTF * pSender) +{ + if (! m_bAction) + { + m_pTextField[0]->runAction(m_pTextFieldAction); + m_bAction = true; + } + return false; +} + +bool TextFieldTTFTest::onTextFieldDetachWithIME(CCTextFieldTTF * pSender) +{ + if (m_bAction) + { + m_pTextField[0]->stopAction(m_pTextFieldAction); + m_pTextField[0]->setOpacity(255); + m_bAction = false; + } + return false; +} + +bool TextFieldTTFTest::onTextFieldInsertText(CCTextFieldTTF * pSender, const char * text, int nLen) +{ + // if the textfield's char count more than m_nCharLimit, doesn't insert text anymore. + if (pSender->getCharCount() >= m_nCharLimit) + { + return true; + } + + // if insert enter, treat as default + if ('\n' == *text) + { + return false; + } + + // create a insert text sprite and do some action + CCLabelTTF * label = CCLabelTTF::labelWithString(text, FONT_NAME, FONT_SIZE); + this->addChild(label); + ccColor3B color = { 226, 121, 7}; + label->setColor(color); + + // move the sprite from top to position + CCPoint endPos = pSender->getPosition(); + if (pSender->getCharCount()) + { + endPos.x += pSender->getContentSize().width / 2; + } + CCSize inputTextSize = label->getContentSize(); + CCPoint beginPos(endPos.x, CCDirector::sharedDirector()->getWinSize().height + inputTextSize.height * 2); + + ccTime duration = 0.5; + label->setPosition(beginPos); + label->setScale(4); + + CCAction * seq = CCSequence::actions( + CCSpawn::actions( + CCMoveTo::actionWithDuration(duration, endPos), + CCScaleTo::actionWithDuration(duration, 1), + CCFadeOut::actionWithDuration(duration), + 0), + CCCallFuncN::actionWithTarget(this, callfuncN_selector(TextFieldTTFTest::callbackRemoveNodeWhenDidAction)), + 0); + label->runAction(seq); + return false; +} + +bool TextFieldTTFTest::onTextFieldDeleteBackward(CCTextFieldTTF * pSender, const char * delText, int nLen) +{ + // create a delete text sprite and do some action + CCLabelTTF * label = CCLabelTTF::labelWithString(delText, FONT_NAME, FONT_SIZE); + this->addChild(label); + + // move the sprite to fly out + CCPoint beginPos = pSender->getPosition(); + if (pSender->getCharCount()) + { + beginPos.x += pSender->getContentSize().width / 2; + } + else + { + beginPos.x -= label->getContentSize().width / 2; + } + CCSize winSize = CCDirector::sharedDirector()->getWinSize(); + CCPoint endPos(- winSize.width / 4, winSize.height * (0.5 + (float)rand() / (2 * RAND_MAX))); + + ccTime duration = 1; + ccTime rotateDuration = 0.2f; + int repeatTime = 5; + label->setPosition(beginPos); + + CCAction * seq = CCSequence::actions( + CCSpawn::actions( + CCMoveTo::actionWithDuration(duration, endPos), + CCRepeat::actionWithAction( + CCRotateBy::actionWithDuration(rotateDuration, (rand()%2) ? 360 : -360), + repeatTime), + CCFadeOut::actionWithDuration(duration), + 0), + CCCallFuncN::actionWithTarget(this, callfuncN_selector(TextFieldTTFTest::callbackRemoveNodeWhenDidAction)), + 0); + label->runAction(seq); + return false; +} + +bool TextFieldTTFTest::onDraw(CCTextFieldTTF * pSender) +{ + return false; +} + +void TextFieldTTFTest::callbackRemoveNodeWhenDidAction(CCNode * pNode) +{ + this->removeChild(pNode, true); +} + ////////////////////////////////////////////////////////////////////////// // implement TextInputTestScene ////////////////////////////////////////////////////////////////////////// diff --git a/tests/tests/TextInputTest/TextInputTest.h b/tests/tests/TextInputTest/TextInputTest.h index e1a3653ed3..4e83121ee4 100644 --- a/tests/tests/TextInputTest/TextInputTest.h +++ b/tests/tests/TextInputTest/TextInputTest.h @@ -35,18 +35,32 @@ protected: CCNode * m_pTrackNode; }; -class TextFieldTTFTest : public KeyboardNotificationLayer +class TextFieldTTFTest : public KeyboardNotificationLayer, public CCTextFieldDelegate { CCPoint m_beginPos; CCTextFieldTTF * m_pTextField[2]; + CCAction * m_pTextFieldAction; + bool m_bAction; int m_nSelected; -public: - TextFieldTTFTest(); + int m_nCharLimit; // the textfield max char limit +public: virtual std::string subtitle(); + // CCLayer + virtual void onEnter(); + virtual void onExit(); virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); + + // CCTextFieldDelegate + virtual bool onTextFieldAttachWithIME(CCTextFieldTTF * pSender); + virtual bool onTextFieldDetachWithIME(CCTextFieldTTF * pSender); + virtual bool onTextFieldInsertText(CCTextFieldTTF * pSender, const char * text, int nLen); + virtual bool onTextFieldDeleteBackward(CCTextFieldTTF * pSender, const char * delText, int nLen); + virtual bool onDraw(CCTextFieldTTF * pSender); + + void callbackRemoveNodeWhenDidAction(CCNode * pNode); }; class TextInputTestScene : public TestScene