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__
#define __CC_IME_DELEGATE_H__
#include "CCCommon.h"
#include "CCGeometry.h"
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
{
public:
virtual ~CCIMEDelegate();
bool attachWithIME();
virtual bool attachWithIME();
virtual bool detachWithIME();
protected:
friend class CCIMEDispatcher;
@ -47,35 +55,39 @@ protected:
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.
*/
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.
*/
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.
*/
virtual void deleteBackward() = 0;
virtual void deleteBackward() {}
//////////////////////////////////////////////////////////////////////////
// keyboard show/hide notification
//////////////////////////////////////////////////////////////////////////
virtual void keyboardWillShow(CCRect& begin, CCRect& end) {}
virtual void keyboardDidShow(CCRect& begin, CCRect& end) {}
virtual void keyboardWillHide(CCRect& begin, CCRect& end) {}
virtual void keyboardDidHide(CCRect& begin, CCRect& end) {}
virtual void keyboardWillShow(CCIMEKeyboardNotificationInfo& info) {}
virtual void keyboardDidShow(CCIMEKeyboardNotificationInfo& info) {}
virtual void keyboardWillHide(CCIMEKeyboardNotificationInfo& info) {}
virtual void keyboardDidHide(CCIMEKeyboardNotificationInfo& info) {}
protected:
CCIMEDelegate();

View File

@ -25,12 +25,10 @@ THE SOFTWARE.
#ifndef __CC_IME_DISPATCHER_H__
#define __CC_IME_DISPATCHER_H__
#include "CCGeometry.h"
#include "CCIMEDelegate.h"
NS_CC_BEGIN;
class CCIMEDelegate;
/**
@brief Input Method Edit Message Dispatcher.
*/
@ -62,10 +60,10 @@ public:
//////////////////////////////////////////////////////////////////////////
// dispatch keyboard notification
//////////////////////////////////////////////////////////////////////////
void dispatchKeyboardWillShow(CCRect& begin, CCRect& end);
void dispatchKeyboardDidShow(CCRect& begin, CCRect& end);
void dispatchKeyboardWillHide(CCRect& begin, CCRect& end);
void dispatchKeyboardDidHide(CCRect& begin, CCRect& end);
void dispatchKeyboardWillShow(CCIMEKeyboardNotificationInfo& info);
void dispatchKeyboardDidShow(CCIMEKeyboardNotificationInfo& info);
void dispatchKeyboardWillHide(CCIMEKeyboardNotificationInfo& info);
void dispatchKeyboardDidHide(CCIMEKeyboardNotificationInfo& info);
protected:
friend class CCIMEDelegate;
@ -81,6 +79,7 @@ protected:
can attach with ime, return true, otherwise return false.
*/
bool attachDelegateWithIME(CCIMEDelegate * pDelegate);
bool detachDelegateWithIME(CCIMEDelegate * pDelegate);
/**
@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);
/**
@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
@ -83,8 +88,7 @@ protected:
//////////////////////////////////////////////////////////////////////////
virtual bool canAttachWithIME();
virtual bool canDetatchWithIME();
virtual void detatchWithIME();
virtual bool canDetachWithIME();
virtual void insertText(const char * text, int len);
virtual void deleteBackward();

View File

@ -177,6 +177,25 @@ static cocos2d::CCTouch *s_pTouches[MAX_TOUCHES];
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
{
CGSize bound = [self bounds].size;
@ -502,7 +521,7 @@ static cocos2d::CCTouch *s_pTouches[MAX_TOUCHES];
}
#pragma mark -
#pragma mark EAGLView - UIKeyInput
#pragma mark UIKeyInput protocol
- (BOOL)hasText
{
@ -520,6 +539,14 @@ static cocos2d::CCTouch *s_pTouches[MAX_TOUCHES];
cocos2d::CCIMEDispatcher::sharedDispatcher()->dispatchDeleteBackward();
}
#pragma mark -
#pragma mark UITextInputTrait protocol
-(UITextAutocapitalizationType) autocapitalizationType
{
return UITextAutocapitalizationTypeNone;
}
#pragma mark -
#pragma mark UITextInput protocol
@ -691,4 +718,99 @@ static cocos2d::CCTouch *s_pTouches[MAX_TOUCHES];
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

View File

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

View File

@ -134,25 +134,31 @@ bool CCTextFieldTTF::attachWithIME()
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()
{
return true;
}
bool CCTextFieldTTF::canDetatchWithIME()
bool CCTextFieldTTF::canDetachWithIME()
{
return true;
}
void CCTextFieldTTF::detatchWithIME()
{
CCEGLView * pGlView = CCDirector::sharedDirector()->getOpenGLView();
if (pGlView)
{
pGlView->setIMEKeyboardState(false);
}
}
void CCTextFieldTTF::insertText(const char * text, int len)
{
std::string sInsert(text, len);

View File

@ -1 +1 @@
38bdb35f5d331e4f326831460ce303bfed7e29bd
1684c4f675e0f74eb4b6b0dfb3b990900632d290

View File

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

View File

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

View File

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