keyboard notification message on ios and TextFieldTTF test code OK.

This commit is contained in:
yangws 2011-04-26 16:33:20 +08:00
parent 252f3efe1a
commit 9b08f4add6
10 changed files with 249 additions and 67 deletions

View File

@ -25,19 +25,27 @@ THE SOFTWARE.
#ifndef __CC_IME_DELEGATE_H__ #ifndef __CC_IME_DELEGATE_H__
#define __CC_IME_DELEGATE_H__ #define __CC_IME_DELEGATE_H__
#include "CCCommon.h" #include "CCGeometry.h"
NS_CC_BEGIN; NS_CC_BEGIN;
typedef struct
{
CCRect begin; // the soft keyboard rectangle when animatin begin
CCRect end; // the soft keyboard rectangle when animatin end
float duration; // the soft keyboard animation duration
} CCIMEKeyboardNotificationInfo;
/** /**
@brief Input method editor protocol. @brief Input method editor delegate.
*/ */
class CC_DLL CCIMEDelegate class CC_DLL CCIMEDelegate
{ {
public: public:
virtual ~CCIMEDelegate(); virtual ~CCIMEDelegate();
bool attachWithIME(); virtual bool attachWithIME();
virtual bool detachWithIME();
protected: protected:
friend class CCIMEDispatcher; friend class CCIMEDispatcher;
@ -47,35 +55,39 @@ protected:
Called by CCIMEDispatcher. Called by CCIMEDispatcher.
*/ */
virtual bool canAttachWithIME() = 0; virtual bool canAttachWithIME() { return false; }
/**
@brief When the delegate detach with IME, this method call by CCIMEDispatcher.
*/
virtual void didAttachWithIME() {}
/** /**
@brief Decide the delegate instance can stop receive ime message or not. @brief Decide the delegate instance can stop receive ime message or not.
*/ */
virtual bool canDetatchWithIME() = 0; virtual bool canDetachWithIME() { return false; }
/** /**
@brief Input end and release keyboard. @brief When the delegate detach with IME, this method call by CCIMEDispatcher.
*/ */
virtual void detatchWithIME() = 0; virtual void didDetachWithIME() {}
/** /**
@brief Called by CCIMEDispatcher when some text input from IME. @brief Called by CCIMEDispatcher when some text input from IME.
*/ */
virtual void insertText(const char * text, int len) = 0; virtual void insertText(const char * text, int len) {}
/** /**
@brief Called by CCIMEDispatcher when user clicked the backward key. @brief Called by CCIMEDispatcher when user clicked the backward key.
*/ */
virtual void deleteBackward() = 0; virtual void deleteBackward() {}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// keyboard show/hide notification // keyboard show/hide notification
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
virtual void keyboardWillShow(CCRect& begin, CCRect& end) {} virtual void keyboardWillShow(CCIMEKeyboardNotificationInfo& info) {}
virtual void keyboardDidShow(CCRect& begin, CCRect& end) {} virtual void keyboardDidShow(CCIMEKeyboardNotificationInfo& info) {}
virtual void keyboardWillHide(CCRect& begin, CCRect& end) {} virtual void keyboardWillHide(CCIMEKeyboardNotificationInfo& info) {}
virtual void keyboardDidHide(CCRect& begin, CCRect& end) {} virtual void keyboardDidHide(CCIMEKeyboardNotificationInfo& info) {}
protected: protected:
CCIMEDelegate(); CCIMEDelegate();

View File

@ -25,12 +25,10 @@ THE SOFTWARE.
#ifndef __CC_IME_DISPATCHER_H__ #ifndef __CC_IME_DISPATCHER_H__
#define __CC_IME_DISPATCHER_H__ #define __CC_IME_DISPATCHER_H__
#include "CCGeometry.h" #include "CCIMEDelegate.h"
NS_CC_BEGIN; NS_CC_BEGIN;
class CCIMEDelegate;
/** /**
@brief Input Method Edit Message Dispatcher. @brief Input Method Edit Message Dispatcher.
*/ */
@ -62,10 +60,10 @@ public:
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// dispatch keyboard notification // dispatch keyboard notification
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void dispatchKeyboardWillShow(CCRect& begin, CCRect& end); void dispatchKeyboardWillShow(CCIMEKeyboardNotificationInfo& info);
void dispatchKeyboardDidShow(CCRect& begin, CCRect& end); void dispatchKeyboardDidShow(CCIMEKeyboardNotificationInfo& info);
void dispatchKeyboardWillHide(CCRect& begin, CCRect& end); void dispatchKeyboardWillHide(CCIMEKeyboardNotificationInfo& info);
void dispatchKeyboardDidHide(CCRect& begin, CCRect& end); void dispatchKeyboardDidHide(CCIMEKeyboardNotificationInfo& info);
protected: protected:
friend class CCIMEDelegate; friend class CCIMEDelegate;
@ -81,6 +79,7 @@ protected:
can attach with ime, return true, otherwise return false. can attach with ime, return true, otherwise return false.
*/ */
bool attachDelegateWithIME(CCIMEDelegate * pDelegate); bool attachDelegateWithIME(CCIMEDelegate * pDelegate);
bool detachDelegateWithIME(CCIMEDelegate * pDelegate);
/** /**
@brief remove the delegate from the delegates who concern ime msg @brief remove the delegate from the delegates who concern ime msg

View File

@ -53,9 +53,14 @@ public:
bool initWithPlaceHolder(const char *placeholder, const char *fontName, float fontSize); bool initWithPlaceHolder(const char *placeholder, const char *fontName, float fontSize);
/** /**
@brief Get keyboard ready and waiting for input. @brief Open keyboard and receive input text.
*/ */
bool attachWithIME(); virtual bool attachWithIME();
/**
@brief End text input and close keyboard.
*/
virtual bool detachWithIME();
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// properties // properties
@ -83,8 +88,7 @@ protected:
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
virtual bool canAttachWithIME(); virtual bool canAttachWithIME();
virtual bool canDetatchWithIME(); virtual bool canDetachWithIME();
virtual void detatchWithIME();
virtual void insertText(const char * text, int len); virtual void insertText(const char * text, int len);
virtual void deleteBackward(); virtual void deleteBackward();

View File

@ -177,6 +177,25 @@ static cocos2d::CCTouch *s_pTouches[MAX_TOUCHES];
return self; return self;
} }
- (void)didMoveToWindow;
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onUIKeyboardNotification:)
name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onUIKeyboardNotification:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onUIKeyboardNotification:)
name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onUIKeyboardNotification:)
name:UIKeyboardDidHideNotification object:nil];
}
-(int) getWidth -(int) getWidth
{ {
CGSize bound = [self bounds].size; CGSize bound = [self bounds].size;
@ -502,7 +521,7 @@ static cocos2d::CCTouch *s_pTouches[MAX_TOUCHES];
} }
#pragma mark - #pragma mark -
#pragma mark EAGLView - UIKeyInput #pragma mark UIKeyInput protocol
- (BOOL)hasText - (BOOL)hasText
{ {
@ -520,6 +539,14 @@ static cocos2d::CCTouch *s_pTouches[MAX_TOUCHES];
cocos2d::CCIMEDispatcher::sharedDispatcher()->dispatchDeleteBackward(); cocos2d::CCIMEDispatcher::sharedDispatcher()->dispatchDeleteBackward();
} }
#pragma mark -
#pragma mark UITextInputTrait protocol
-(UITextAutocapitalizationType) autocapitalizationType
{
return UITextAutocapitalizationTypeNone;
}
#pragma mark - #pragma mark -
#pragma mark UITextInput protocol #pragma mark UITextInput protocol
@ -691,4 +718,99 @@ static cocos2d::CCTouch *s_pTouches[MAX_TOUCHES];
return nil; return nil;
} }
#pragma mark -
#pragma mark UIKeyboard notification
- (void)onUIKeyboardNotification:(NSNotification *)notif;
{
NSString * type = notif.name;
NSDictionary* info = [notif userInfo];
CGRect begin = [self convertRect:
[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]
fromView:self];
CGRect end = [self convertRect:
[[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]
fromView:self];
double aniDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGSize viewSize = self.frame.size;
CGFloat tmp;
switch ([[UIApplication sharedApplication] statusBarOrientation])
{
case UIInterfaceOrientationPortrait:
begin.origin.y = viewSize.height - begin.origin.y - begin.size.height;
end.origin.y = viewSize.height - end.origin.y - end.size.height;
break;
case UIInterfaceOrientationPortraitUpsideDown:
begin.origin.x = viewSize.width - (begin.origin.x + begin.size.width);
end.origin.x = viewSize.width - (end.origin.x + end.size.width);
break;
case UIInterfaceOrientationLandscapeLeft:
tmp = begin.size.width;
begin.size.width = begin.size.height;
begin.size.height = tmp;
tmp = end.size.width;
end.size.width = end.size.height;
end.size.height = tmp;
tmp = begin.origin.x;
begin.origin.x = begin.origin.y;
begin.origin.y = viewSize.width - tmp - begin.size.height;
tmp = end.origin.x;
end.origin.x = end.origin.y;
end.origin.y = viewSize.width - tmp - end.size.height;
break;
case UIInterfaceOrientationLandscapeRight:
tmp = begin.size.width;
begin.size.width = begin.size.height;
begin.size.height = tmp;
tmp = end.size.width;
end.size.width = end.size.height;
end.size.height = tmp;
tmp = begin.origin.x;
begin.origin.x = begin.origin.y;
begin.origin.y = tmp;
tmp = end.origin.x;
end.origin.x = end.origin.y;
end.origin.y = tmp;
break;
default:
break;
}
cocos2d::CCIMEKeyboardNotificationInfo notiInfo;
notiInfo.begin = cocos2d::CCRect(begin.origin.x,
begin.origin.y,
begin.size.width,
begin.size.height);
notiInfo.end = cocos2d::CCRect(end.origin.x,
end.origin.y,
end.size.width,
end.size.height);
notiInfo.duration = (float)aniDuration;
cocos2d::CCIMEDispatcher* dispatcher = cocos2d::CCIMEDispatcher::sharedDispatcher();
if (UIKeyboardWillShowNotification == type)
{
dispatcher->dispatchKeyboardWillShow(notiInfo);
}
else if (UIKeyboardDidShowNotification == type)
{
dispatcher->dispatchKeyboardDidShow(notiInfo);
}
else if (UIKeyboardWillHideNotification == type)
{
dispatcher->dispatchKeyboardWillHide(notiInfo);
}
else if (UIKeyboardDidHideNotification == type)
{
dispatcher->dispatchKeyboardDidHide(notiInfo);
}
}
@end @end

View File

@ -26,8 +26,6 @@ THE SOFTWARE.
#include <list> #include <list>
#include "CCIMEDelegate.h"
NS_CC_BEGIN; NS_CC_BEGIN;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -49,6 +47,11 @@ bool CCIMEDelegate::attachWithIME()
return CCIMEDispatcher::sharedDispatcher()->attachDelegateWithIME(this); return CCIMEDispatcher::sharedDispatcher()->attachDelegateWithIME(this);
} }
bool CCIMEDelegate::detachWithIME()
{
return CCIMEDispatcher::sharedDispatcher()->detachDelegateWithIME(this);
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
typedef std::list< CCIMEDelegate * > DelegateList; typedef std::list< CCIMEDelegate * > DelegateList;
@ -72,7 +75,7 @@ public:
void init() void init()
{ {
m_DelegateWithIme = m_DelegateList.end(); m_DelegateWithIme = 0;
} }
DelegateIter findDelegate(CCIMEDelegate* pDelegate) DelegateIter findDelegate(CCIMEDelegate* pDelegate)
@ -88,8 +91,8 @@ public:
return end; return end;
} }
DelegateList m_DelegateList; DelegateList m_DelegateList;
DelegateIter m_DelegateWithIme; CCIMEDelegate* m_DelegateWithIme;
}; };
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -138,20 +141,40 @@ bool CCIMEDispatcher::attachDelegateWithIME(CCIMEDelegate * pDelegate)
// if pDelegate is not in delegate list, return // if pDelegate is not in delegate list, return
CC_BREAK_IF(end == iter); CC_BREAK_IF(end == iter);
if (m_pImpl->m_DelegateWithIme != end) if (m_pImpl->m_DelegateWithIme)
{ {
// if old delegate canDetatchWithIME return false // if old delegate canDetachWithIME return false
// or pDelegate canAttachWithIME return false, // or pDelegate canAttachWithIME return false,
// do nothing. // do nothing.
CC_BREAK_IF(! (*(m_pImpl->m_DelegateWithIme))->canDetatchWithIME() CC_BREAK_IF(! m_pImpl->m_DelegateWithIme->canDetachWithIME()
|| ! pDelegate->canAttachWithIME()); || ! pDelegate->canAttachWithIME());
// detach first // detach first
CCIMEDelegate * pOldDelegate = *(m_pImpl->m_DelegateWithIme); CCIMEDelegate * pOldDelegate = m_pImpl->m_DelegateWithIme;
m_pImpl->m_DelegateWithIme = end; m_pImpl->m_DelegateWithIme = 0;
pOldDelegate->detatchWithIME(); pOldDelegate->didDetachWithIME();
} }
m_pImpl->m_DelegateWithIme = iter; m_pImpl->m_DelegateWithIme = *iter;
pDelegate->didAttachWithIME();
bRet = true;
} while (0);
return bRet;
}
bool CCIMEDispatcher::detachDelegateWithIME(CCIMEDelegate * pDelegate)
{
bool bRet = false;
do
{
CC_BREAK_IF(! m_pImpl || ! pDelegate);
// if pDelegate is not the current delegate attached with ime, return
CC_BREAK_IF(m_pImpl->m_DelegateWithIme != pDelegate);
CC_BREAK_IF(! pDelegate->canDetachWithIME());
m_pImpl->m_DelegateWithIme = 0;
pDelegate->didDetachWithIME();
bRet = true; bRet = true;
} while (0); } while (0);
return bRet; return bRet;
@ -167,10 +190,11 @@ void CCIMEDispatcher::removeDelegate(CCIMEDelegate* pDelegate)
DelegateIter end = m_pImpl->m_DelegateList.end(); DelegateIter end = m_pImpl->m_DelegateList.end();
CC_BREAK_IF(end == iter); CC_BREAK_IF(end == iter);
if (m_pImpl->m_DelegateWithIme != end if (m_pImpl->m_DelegateWithIme)
&&*iter == *(m_pImpl->m_DelegateWithIme))
if (*iter == m_pImpl->m_DelegateWithIme)
{ {
m_pImpl->m_DelegateWithIme == end; m_pImpl->m_DelegateWithIme = 0;
} }
m_pImpl->m_DelegateList.erase(iter); m_pImpl->m_DelegateList.erase(iter);
} while (0); } while (0);
@ -187,10 +211,9 @@ void CCIMEDispatcher::dispatchInsertText(const char * pText, int nLen)
CC_BREAK_IF(! m_pImpl || ! pText || nLen <= 0); CC_BREAK_IF(! m_pImpl || ! pText || nLen <= 0);
// there is no delegate attach with ime // there is no delegate attach with ime
CC_BREAK_IF(m_pImpl->m_DelegateWithIme == m_pImpl->m_DelegateList.end()); CC_BREAK_IF(! m_pImpl->m_DelegateWithIme);
CCIMEDelegate * pDelegate = *(m_pImpl->m_DelegateWithIme); m_pImpl->m_DelegateWithIme->insertText(pText, nLen);
pDelegate->insertText(pText, nLen);
} while (0); } while (0);
} }
@ -201,10 +224,9 @@ void CCIMEDispatcher::dispatchDeleteBackward()
CC_BREAK_IF(! m_pImpl); CC_BREAK_IF(! m_pImpl);
// there is no delegate attach with ime // there is no delegate attach with ime
CC_BREAK_IF(m_pImpl->m_DelegateWithIme == m_pImpl->m_DelegateList.end()); CC_BREAK_IF(! m_pImpl->m_DelegateWithIme);
CCIMEDelegate * pDelegate = *(m_pImpl->m_DelegateWithIme); m_pImpl->m_DelegateWithIme->deleteBackward();
pDelegate->deleteBackward();
} while (0); } while (0);
} }
@ -212,7 +234,7 @@ void CCIMEDispatcher::dispatchDeleteBackward()
// dispatch keyboard message // dispatch keyboard message
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void CCIMEDispatcher::dispatchKeyboardWillShow(CCRect& begin, CCRect& end) void CCIMEDispatcher::dispatchKeyboardWillShow(CCIMEKeyboardNotificationInfo& info)
{ {
if (m_pImpl) if (m_pImpl)
{ {
@ -223,13 +245,13 @@ void CCIMEDispatcher::dispatchKeyboardWillShow(CCRect& begin, CCRect& end)
pDelegate = *(first); pDelegate = *(first);
if (pDelegate) if (pDelegate)
{ {
pDelegate->keyboardWillShow(begin, end); pDelegate->keyboardWillShow(info);
} }
} }
} }
} }
void CCIMEDispatcher::dispatchKeyboardDidShow(CCRect& begin, CCRect& end) void CCIMEDispatcher::dispatchKeyboardDidShow(CCIMEKeyboardNotificationInfo& info)
{ {
if (m_pImpl) if (m_pImpl)
{ {
@ -240,13 +262,13 @@ void CCIMEDispatcher::dispatchKeyboardDidShow(CCRect& begin, CCRect& end)
pDelegate = *(first); pDelegate = *(first);
if (pDelegate) if (pDelegate)
{ {
pDelegate->keyboardDidShow(begin, end); pDelegate->keyboardDidShow(info);
} }
} }
} }
} }
void CCIMEDispatcher::dispatchKeyboardWillHide(CCRect& begin, CCRect& end) void CCIMEDispatcher::dispatchKeyboardWillHide(CCIMEKeyboardNotificationInfo& info)
{ {
if (m_pImpl) if (m_pImpl)
{ {
@ -257,13 +279,13 @@ void CCIMEDispatcher::dispatchKeyboardWillHide(CCRect& begin, CCRect& end)
pDelegate = *(first); pDelegate = *(first);
if (pDelegate) if (pDelegate)
{ {
pDelegate->keyboardWillHide(begin, end); pDelegate->keyboardWillHide(info);
} }
} }
} }
} }
void CCIMEDispatcher::dispatchKeyboardDidHide(CCRect& begin, CCRect& end) void CCIMEDispatcher::dispatchKeyboardDidHide(CCIMEKeyboardNotificationInfo& info)
{ {
if (m_pImpl) if (m_pImpl)
{ {
@ -274,7 +296,7 @@ void CCIMEDispatcher::dispatchKeyboardDidHide(CCRect& begin, CCRect& end)
pDelegate = *(first); pDelegate = *(first);
if (pDelegate) if (pDelegate)
{ {
pDelegate->keyboardDidHide(begin, end); pDelegate->keyboardDidHide(info);
} }
} }
} }

View File

@ -134,25 +134,31 @@ bool CCTextFieldTTF::attachWithIME()
return bRet; return bRet;
} }
bool CCTextFieldTTF::detachWithIME()
{
bool bRet = CCIMEDelegate::detachWithIME();
if (bRet)
{
// close keyboard
CCEGLView * pGlView = CCDirector::sharedDirector()->getOpenGLView();
if (pGlView)
{
pGlView->setIMEKeyboardState(false);
}
}
return bRet;
}
bool CCTextFieldTTF::canAttachWithIME() bool CCTextFieldTTF::canAttachWithIME()
{ {
return true; return true;
} }
bool CCTextFieldTTF::canDetatchWithIME() bool CCTextFieldTTF::canDetachWithIME()
{ {
return true; return true;
} }
void CCTextFieldTTF::detatchWithIME()
{
CCEGLView * pGlView = CCDirector::sharedDirector()->getOpenGLView();
if (pGlView)
{
pGlView->setIMEKeyboardState(false);
}
}
void CCTextFieldTTF::insertText(const char * text, int len) void CCTextFieldTTF::insertText(const char * text, int len)
{ {
std::string sInsert(text, len); std::string sInsert(text, len);

View File

@ -1 +1 @@
38bdb35f5d331e4f326831460ce303bfed7e29bd 1684c4f675e0f74eb4b6b0dfb3b990900632d290

View File

@ -923,6 +923,18 @@
> >
</File> </File>
</Filter> </Filter>
<Filter
Name="TextInputTest"
>
<File
RelativePath="..\tests\TextInputTest\TextInputTest.cpp"
>
</File>
<File
RelativePath="..\tests\TextInputTest\TextInputTest.h"
>
</File>
</Filter>
</Filter> </Filter>
</Filter> </Filter>
</Files> </Files>

View File

@ -62,8 +62,10 @@ static TestScene* CreateTestScene(int nIdx)
#endif #endif
#endif #endif
#endif #endif
case TEST_ATLAS: case TEST_LABEL:
pScene = new AtlasTestScene(); break; pScene = new AtlasTestScene(); break;
case TEST_TEXT_INPUT:
pScene = new TextInputTestScene(); break;
case TEST_SPRITE: case TEST_SPRITE:
pScene = new SpriteTestScene(); break; pScene = new SpriteTestScene(); break;
case TEST_SCHEDULER: case TEST_SCHEDULER:

View File

@ -21,6 +21,7 @@
#include "TileMapTest/TileMapTest.h" #include "TileMapTest/TileMapTest.h"
#include "IntervalTest/IntervalTest.h" #include "IntervalTest/IntervalTest.h"
#include "LabelTest/LabelTest.h" #include "LabelTest/LabelTest.h"
#include "TextInputTest/TextInputTest.h"
#include "SpriteTest/SpriteTest.h" #include "SpriteTest/SpriteTest.h"
#include "SchedulerTest/SchedulerTest.h" #include "SchedulerTest/SchedulerTest.h"
#include "RenderTextureTest/RenderTextureTest.h" #include "RenderTextureTest/RenderTextureTest.h"
@ -66,7 +67,8 @@ enum
TEST_TILE_MAP, TEST_TILE_MAP,
TEST_INTERVAL, TEST_INTERVAL,
TEST_CHIPMUNK, TEST_CHIPMUNK,
TEST_ATLAS, TEST_LABEL,
TEST_TEXT_INPUT,
TEST_SPRITE, TEST_SPRITE,
TEST_SCHEDULER, TEST_SCHEDULER,
TEST_RENDERTEXTURE, TEST_RENDERTEXTURE,
@ -105,6 +107,7 @@ const std::string g_aTestNames[TESTS_COUNT] = {
"IntervalTest", "IntervalTest",
"ChipmunkTest", "ChipmunkTest",
"LabelTest", "LabelTest",
"TextInputTest",
"SpriteTest", "SpriteTest",
"SchdulerTest", "SchdulerTest",
"RenderTextureTest", "RenderTextureTest",