Workaround for some problems due to UITextField of CCEditBoxImplIOS is attached as a view above OpenGL view. It has a topmost touch priority higher than any other CCNode objects, and also cannot be veiled by any other CCNode objects.

In this change, UITextField is visible only when the CCEditBox is in edit mode. And in non-edit mode, UITextField is hidden and CCLabelTTF is shown instead with all same attributes at the same place.
This commit is contained in:
Neo Kim 2013-03-12 18:23:12 +09:00
parent ae1c64573e
commit ec8241058c
7 changed files with 186 additions and 49 deletions

25
extensions/GUI/CCEditBox/CCEditBox.cpp Normal file → Executable file
View File

@ -48,7 +48,7 @@ CCEditBox::~CCEditBox(void)
void CCEditBox::touchDownAction(CCObject *sender, CCControlEvent controlEvent)
{
{
m_pEditBoxImpl->openKeyboard();
}
@ -118,10 +118,12 @@ const char* CCEditBox::getText(void)
{
if (m_pEditBoxImpl != NULL)
{
return m_pEditBoxImpl->getText();
const char* pText = m_pEditBoxImpl->getText();
if(pText != NULL)
return pText;
}
return NULL;
return "";
}
void CCEditBox::setFont(const char* pFontName, int fontSize)
@ -268,6 +270,15 @@ void CCEditBox::visit(void)
}
}
void CCEditBox::onEnter(void)
{
CCControlButton::onEnter();
if (m_pEditBoxImpl != NULL)
{
m_pEditBoxImpl->onEnter();
}
}
void CCEditBox::onExit(void)
{
CCControlButton::onExit();
@ -280,7 +291,9 @@ void CCEditBox::onExit(void)
static CCRect getRect(CCNode * pNode)
{
return pNode->boundingBox();
CCSize contentSize = pNode->getContentSize();
CCRect rect = CCRectMake(0, 0, contentSize.width, contentSize.height);
return CCRectApplyAffineTransform(rect, pNode->nodeToWorldTransform());
}
void CCEditBox::keyboardWillShow(CCIMEKeyboardNotificationInfo& info)
@ -312,7 +325,7 @@ void CCEditBox::keyboardWillShow(CCIMEKeyboardNotificationInfo& info)
void CCEditBox::keyboardDidShow(CCIMEKeyboardNotificationInfo& info)
{
}
void CCEditBox::keyboardWillHide(CCIMEKeyboardNotificationInfo& info)
@ -326,7 +339,7 @@ void CCEditBox::keyboardWillHide(CCIMEKeyboardNotificationInfo& info)
void CCEditBox::keyboardDidHide(CCIMEKeyboardNotificationInfo& info)
{
}

1
extensions/GUI/CCEditBox/CCEditBox.h Normal file → Executable file
View File

@ -290,6 +290,7 @@ public:
virtual void setContentSize(const CCSize& size);
virtual void setAnchorPoint(const CCPoint& anchorPoint);
virtual void visit(void);
virtual void onEnter(void);
virtual void onExit(void);
virtual void keyboardWillShow(CCIMEKeyboardNotificationInfo& info);
virtual void keyboardDidShow(CCIMEKeyboardNotificationInfo& info);

1
extensions/GUI/CCEditBox/CCEditBoxImpl.h Normal file → Executable file
View File

@ -64,6 +64,7 @@ public:
virtual void setContentSize(const CCSize& size) = 0;
virtual void setAnchorPoint(const CCPoint& anchorPoint) = 0;
virtual void visit(void) = 0;
virtual void onEnter(void) = 0;
void setDelegate(CCEditBoxDelegate* pDelegate) { m_pDelegate = pDelegate; };

67
extensions/GUI/CCEditBox/CCEditBoxImplAndroid.cpp Normal file → Executable file
View File

@ -55,28 +55,30 @@ CCEditBoxImplAndroid::CCEditBoxImplAndroid(CCEditBox* pEditText)
CCEditBoxImplAndroid::~CCEditBoxImplAndroid()
{
}
void CCEditBoxImplAndroid::doAnimationWhenKeyboardMove(float duration, float distance)
{ // don't need to be implemented on android platform.
}
static const int CC_EDIT_BOX_PADDING = 5;
bool CCEditBoxImplAndroid::initWithSize(const CCSize& size)
{
int fontSize = getFontSizeAccordingHeightJni(size.height-12);
m_pLabel = CCLabelTTF::create("", "", size.height-12);
// align the text vertically center
m_pLabel->setAnchorPoint(ccp(0, 0.5f));
m_pLabel->setPosition(ccp(5, size.height / 2.0f));
m_pLabel->setPosition(ccp(CC_EDIT_BOX_PADDING, size.height / 2.0f));
m_pLabel->setColor(m_colText);
m_pEditBox->addChild(m_pLabel);
m_pLabelPlaceHolder = CCLabelTTF::create("", "", size.height-12);
// align the text vertically center
m_pLabelPlaceHolder->setAnchorPoint(ccp(0, 0.5f));
m_pLabelPlaceHolder->setPosition(ccp(5, size.height / 2.0f));
m_pLabelPlaceHolder->setPosition(ccp(CC_EDIT_BOX_PADDING, size.height / 2.0f));
m_pLabelPlaceHolder->setVisible(false);
m_pLabelPlaceHolder->setColor(m_colPlaceHolder);
m_pEditBox->addChild(m_pLabelPlaceHolder);
@ -153,19 +155,19 @@ void CCEditBoxImplAndroid::setText(const char* pText)
if (pText != NULL)
{
m_strText = pText;
if (m_strText.length() > 0)
{
m_pLabelPlaceHolder->setVisible(false);
std::string strToShow;
if (kEditBoxInputFlagPassword == m_eEditBoxInputFlag)
{
long length = cc_utf8_strlen(m_strText.c_str(), -1);
for (long i = 0; i < length; i++)
{
strToShow.append("*");
strToShow.append("\u25CF");
}
}
else
@ -173,15 +175,23 @@ void CCEditBoxImplAndroid::setText(const char* pText)
strToShow = m_strText;
}
std::string strWithEllipsis = getStringWithEllipsisJni(strToShow.c_str(), m_EditSize.width, m_EditSize.height-12);
m_pLabel->setString(strWithEllipsis.c_str());
m_pLabel->setString(strToShow.c_str());
// Clip the text width to fit to the text box
float fMaxWidth = m_EditSize.width - CC_EDIT_BOX_PADDING * 2;
CCRect clippingRect = m_pLabel->getTextureRect();
if(clippingRect.size.width > fMaxWidth) {
clippingRect.size.width = fMaxWidth;
m_pLabel->setTextureRect(clippingRect);
}
}
else
{
m_pLabelPlaceHolder->setVisible(true);
m_pLabel->setString("");
}
}
}
@ -199,14 +209,14 @@ void CCEditBoxImplAndroid::setPlaceHolder(const char* pText)
{
m_pLabelPlaceHolder->setVisible(true);
}
m_pLabelPlaceHolder->setString(m_strPlaceHolder.c_str());
}
}
void CCEditBoxImplAndroid::setPosition(const CCPoint& pos)
{ // don't need to be implemented on android platform.
}
void CCEditBoxImplAndroid::setVisible(bool visible)
@ -216,7 +226,7 @@ void CCEditBoxImplAndroid::setVisible(bool visible)
void CCEditBoxImplAndroid::setContentSize(const CCSize& size)
{ // don't need to be implemented on android platform.
}
void CCEditBoxImplAndroid::setAnchorPoint(const CCPoint& anchorPoint)
@ -229,11 +239,16 @@ void CCEditBoxImplAndroid::visit(void)
}
void CCEditBoxImplAndroid::onEnter(void)
{ // don't need to be implemented on android platform.
}
static void editBoxCallbackFunc(const char* pText, void* ctx)
{
CCEditBoxImplAndroid* thiz = (CCEditBoxImplAndroid*)ctx;
thiz->setText(pText);
if (thiz->getDelegate() != NULL)
{
thiz->getDelegate()->editBoxTextChanged(thiz->getCCEditBox(), thiz->getText());
@ -248,21 +263,21 @@ void CCEditBoxImplAndroid::openKeyboard()
{
m_pDelegate->editBoxEditingDidBegin(m_pEditBox);
}
showEditTextDialogJNI( m_strPlaceHolder.c_str(),
m_strText.c_str(),
m_eEditBoxInputMode,
m_eEditBoxInputFlag,
m_eKeyboardReturnType,
m_nMaxLength,
editBoxCallbackFunc,
(void*)this );
m_strText.c_str(),
m_eEditBoxInputMode,
m_eEditBoxInputFlag,
m_eKeyboardReturnType,
m_nMaxLength,
editBoxCallbackFunc,
(void*)this );
}
void CCEditBoxImplAndroid::closeKeyboard()
{
}
NS_CC_EXT_END

1
extensions/GUI/CCEditBox/CCEditBoxImplAndroid.h Normal file → Executable file
View File

@ -63,6 +63,7 @@ public:
virtual void setContentSize(const CCSize& size);
virtual void setAnchorPoint(const CCPoint& anchorPoint);
virtual void visit(void);
virtual void onEnter(void);
virtual void doAnimationWhenKeyboardMove(float duration, float distance);
virtual void openKeyboard();
virtual void closeKeyboard();

9
extensions/GUI/CCEditBox/CCEditBoxImplIOS.h Normal file → Executable file
View File

@ -94,11 +94,20 @@ public:
virtual void setContentSize(const CCSize& size);
virtual void setAnchorPoint(const CCPoint& anchorPoint);
virtual void visit(void);
virtual void onEnter(void);
virtual void doAnimationWhenKeyboardMove(float duration, float distance);
virtual void openKeyboard();
virtual void closeKeyboard();
virtual void onEndEditing();
private:
void initInactiveLabels(const CCSize& size);
void setInactiveText(const char* pText);
void adjustTextFieldPosition();
CCLabelTTF* m_pLabel;
CCLabelTTF* m_pLabelPlaceHolder;
CCSize m_tContentSize;
CCPoint m_obPosition;
CCPoint m_obAnchorPoint;

131
extensions/GUI/CCEditBox/CCEditBoxImplIOS.mm Normal file → Executable file
View File

@ -31,11 +31,12 @@
#define getEditBoxImplIOS() ((cocos2d::extension::CCEditBoxImplIOS*)editBox_)
static const int CC_EDIT_BOX_PADDING = 5;
@implementation CustomUITextField
- (CGRect)textRectForBounds:(CGRect)bounds {
float padding = 5.0f;
return CGRectMake(bounds.origin.x + padding, bounds.origin.y + padding,
bounds.size.width - padding*2, bounds.size.height - padding*2);
return CGRectMake(bounds.origin.x + CC_EDIT_BOX_PADDING, bounds.origin.y + CC_EDIT_BOX_PADDING,
bounds.size.width - CC_EDIT_BOX_PADDING*2, bounds.size.height - CC_EDIT_BOX_PADDING*2);
}
- (CGRect)editingRectForBounds:(CGRect)bounds {
return [self textRectForBounds:bounds];
@ -78,6 +79,7 @@
self.editBox = editBox;
[[EAGLView sharedEGLView] addSubview:textField_];
textField_.hidden = YES;
return self;
}while(0);
@ -116,7 +118,6 @@
-(void) closeKeyboard
{
[textField_ resignFirstResponder];
[textField_ removeFromSuperview];
}
- (BOOL)textFieldShouldReturn:(UITextField *)sender
@ -161,6 +162,11 @@
pDelegate->editBoxEditingDidEnd(getEditBoxImplIOS()->getCCEditBox());
pDelegate->editBoxReturn(getEditBoxImplIOS()->getCCEditBox());
}
if(editBox_ != nil)
{
getEditBoxImplIOS()->onEndEditing();
}
return YES;
}
@ -212,6 +218,8 @@ CCEditBoxImpl* __createSystemEditBox(CCEditBox* pEditBox)
CCEditBoxImplIOS::CCEditBoxImplIOS(CCEditBox* pEditText)
: CCEditBoxImpl(pEditText)
, m_pLabel(NULL)
, m_pLabelPlaceHolder(NULL)
, m_systemControl(NULL)
, m_obAnchorPoint(ccp(0.5f, 0.5f))
, m_nMaxTextLength(-1)
@ -249,12 +257,55 @@ bool CCEditBoxImplIOS::initWithSize(const CCSize& size)
m_systemControl = [[EditBoxImplIOS alloc] initWithFrame:rect editBox:this];
if (!m_systemControl) break;
initInactiveLabels(size);
return true;
}while (0);
return false;
}
void CCEditBoxImplIOS::initInactiveLabels(const CCSize& size)
{
const char* pDefaultFontName = [[m_systemControl.textField.font fontName] UTF8String];
float fDefaultFontSize = [m_systemControl.textField.font pointSize];
m_pLabel = CCLabelTTF::create("", pDefaultFontName, fDefaultFontSize);
m_pLabel->setAnchorPoint(ccp(0, 0.5f));
m_pLabel->setPosition(ccp(CC_EDIT_BOX_PADDING, size.height / 2.0f + 1));
m_pLabel->setColor(ccBLACK);
m_pLabel->setVisible(false);
m_pEditBox->addChild(m_pLabel);
m_pLabelPlaceHolder = CCLabelTTF::create("", pDefaultFontName, fDefaultFontSize);
// align the text vertically center
m_pLabelPlaceHolder->setAnchorPoint(ccp(0, 0.5f));
m_pLabelPlaceHolder->setPosition(ccp(CC_EDIT_BOX_PADDING, size.height / 2.0f + 1));
m_pLabelPlaceHolder->setColor(ccGRAY);
m_pEditBox->addChild(m_pLabelPlaceHolder);
}
void CCEditBoxImplIOS::setInactiveText(const char* pText)
{
if(m_systemControl.textField.secureTextEntry == YES)
{
std::string passwordString;
for(int i = 0; i < strlen(pText); ++i)
passwordString.append("\u25CF");
m_pLabel->setString(passwordString.c_str());
}
else
m_pLabel->setString(getText());
// Clip the text width to fit to the text box
float fMaxWidth = m_pEditBox->getContentSize().width - CC_EDIT_BOX_PADDING * 2;
CCRect clippingRect = m_pLabel->getTextureRect();
if(clippingRect.size.width > fMaxWidth) {
clippingRect.size.width = fMaxWidth;
m_pLabel->setTextureRect(clippingRect);
}
}
void CCEditBoxImplIOS::setFont(const char* pFontName, int fontSize)
{
if(pFontName == NULL)
@ -263,11 +314,17 @@ void CCEditBoxImplIOS::setFont(const char* pFontName, int fontSize)
UIFont *textFont = [UIFont fontWithName:fntName size:fontSize];
if(textFont != nil)
[m_systemControl.textField setFont:textFont];
m_pLabel->setFontName(pFontName);
m_pLabel->setFontSize(fontSize);
m_pLabelPlaceHolder->setFontName(pFontName);
m_pLabelPlaceHolder->setFontSize(fontSize);
}
void CCEditBoxImplIOS::setFontColor(const ccColor3B& color)
{
m_systemControl.textField.textColor = [UIColor colorWithRed:color.r / 255.0f green:color.g / 255.0f blue:color.b / 255.0f alpha:1.0f];
m_pLabel->setColor(color);
}
void CCEditBoxImplIOS::setPlaceholderFont(const char* pFontName, int fontSize)
@ -277,7 +334,7 @@ void CCEditBoxImplIOS::setPlaceholderFont(const char* pFontName, int fontSize)
void CCEditBoxImplIOS::setPlaceholderFontColor(const ccColor3B& color)
{
// TODO need to be implemented.
m_pLabelPlaceHolder->setColor(color);
}
void CCEditBoxImplIOS::setInputMode(EditBoxInputMode inputMode)
@ -371,6 +428,19 @@ bool CCEditBoxImplIOS::isEditing()
void CCEditBoxImplIOS::setText(const char* pText)
{
m_systemControl.textField.text = [NSString stringWithUTF8String:pText];
if(m_systemControl.textField.hidden == YES) {
setInactiveText(pText);
if(strlen(pText) == 0)
{
m_pLabel->setVisible(false);
m_pLabelPlaceHolder->setVisible(true);
}
else
{
m_pLabel->setVisible(true);
m_pLabelPlaceHolder->setVisible(false);
}
}
}
const char* CCEditBoxImplIOS::getText(void)
@ -381,6 +451,7 @@ const char* CCEditBoxImplIOS::getText(void)
void CCEditBoxImplIOS::setPlaceHolder(const char* pText)
{
m_systemControl.textField.placeholder = [NSString stringWithUTF8String:pText];
m_pLabelPlaceHolder->setString(pText);
}
static CGPoint convertDesignCoordToScreenCoord(const CCPoint& designCoord, bool bInRetinaMode)
@ -404,12 +475,8 @@ static CGPoint convertDesignCoordToScreenCoord(const CCPoint& designCoord, bool
void CCEditBoxImplIOS::setPosition(const CCPoint& pos)
{
if (!m_obPosition.equals(pos))
{
m_obPosition = pos;
CCPoint designCoord = ccp(pos.x - m_tContentSize.width * m_obAnchorPoint.x, pos.y + m_tContentSize.height * (1 - m_obAnchorPoint.y));
[m_systemControl setPosition:convertDesignCoordToScreenCoord(designCoord, m_bInRetinaMode)];
}
m_obPosition = pos;
adjustTextFieldPosition();
}
void CCEditBoxImplIOS::setVisible(bool visible)
@ -432,16 +499,30 @@ void CCEditBoxImplIOS::setAnchorPoint(const CCPoint& anchorPoint)
void CCEditBoxImplIOS::visit(void)
{
if(getCCEditBox()->getParent()) {
CCPoint p = getCCEditBox()->getParent()->convertToWorldSpace(getCCEditBox()->getPosition());
setPosition(p);
} else {
setPosition(getCCEditBox()->getPosition());
}
}
void CCEditBoxImplIOS::onEnter(void)
{
adjustTextFieldPosition();
}
void CCEditBoxImplIOS::adjustTextFieldPosition()
{
CCSize contentSize = m_pEditBox->getContentSize();
CCRect rect = CCRectMake(0, 0, contentSize.width, contentSize.height);
rect = CCRectApplyAffineTransform(rect, m_pEditBox->nodeToWorldTransform());
CCPoint designCoord = ccp(rect.origin.x, rect.origin.y + rect.size.height);
[m_systemControl setPosition:convertDesignCoordToScreenCoord(designCoord, m_bInRetinaMode)];
}
void CCEditBoxImplIOS::openKeyboard()
{
m_pLabel->setVisible(false);
m_pLabelPlaceHolder->setVisible(false);
m_systemControl.textField.hidden = NO;
[m_systemControl openKeyboard];
}
@ -450,6 +531,22 @@ void CCEditBoxImplIOS::closeKeyboard()
[m_systemControl closeKeyboard];
}
void CCEditBoxImplIOS::onEndEditing()
{
m_systemControl.textField.hidden = YES;
if(strlen(getText()) == 0)
{
m_pLabel->setVisible(false);
m_pLabelPlaceHolder->setVisible(true);
}
else
{
m_pLabel->setVisible(true);
m_pLabelPlaceHolder->setVisible(false);
setInactiveText(getText());
}
}
NS_CC_EXT_END
#endif /* #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) */