2012-04-19 14:35:52 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2010 cocos2d-x.org
|
|
|
|
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include "CCTextFieldTTF.h"
|
|
|
|
|
|
|
|
#include "CCDirector.h"
|
|
|
|
#include "CCEGLView.h"
|
|
|
|
|
|
|
|
NS_CC_BEGIN
|
|
|
|
|
2013-12-18 17:47:20 +08:00
|
|
|
static int _calcCharCount(const char * text)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
int n = 0;
|
|
|
|
char ch = 0;
|
2013-12-18 17:47:20 +08:00
|
|
|
while ((ch = *text))
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
CC_BREAK_IF(! ch);
|
2013-04-19 09:55:29 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
if (0x80 != (0xC0 & ch))
|
|
|
|
{
|
|
|
|
++n;
|
|
|
|
}
|
2013-12-18 17:47:20 +08:00
|
|
|
++text;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// constructor and destructor
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
TextFieldTTF::TextFieldTTF()
|
2013-06-15 14:03:30 +08:00
|
|
|
: _delegate(0)
|
|
|
|
, _charCount(0)
|
2013-11-08 03:58:48 +08:00
|
|
|
, _inputText("")
|
|
|
|
, _placeHolder("") // prevent LabelTTF initWithString assertion
|
2013-06-15 14:03:30 +08:00
|
|
|
, _secureTextEntry(false)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_colorSpaceHolder.r = _colorSpaceHolder.g = _colorSpaceHolder.b = 127;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
TextFieldTTF::~TextFieldTTF()
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// static constructor
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2013-11-08 03:58:48 +08:00
|
|
|
TextFieldTTF * TextFieldTTF::textFieldWithPlaceHolder(const std::string& placeholder, const Size& dimensions, TextHAlignment alignment, const std::string& fontName, float fontSize)
|
2013-04-19 09:55:29 +08:00
|
|
|
{
|
2013-11-08 03:58:48 +08:00
|
|
|
TextFieldTTF *ret = new TextFieldTTF();
|
|
|
|
if(ret && ret->initWithPlaceHolder("", dimensions, alignment, fontName, fontSize))
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-08 03:58:48 +08:00
|
|
|
ret->autorelease();
|
|
|
|
if (placeholder.size()>0)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-08 03:58:48 +08:00
|
|
|
ret->setPlaceHolder(placeholder);
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2013-11-08 03:58:48 +08:00
|
|
|
return ret;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2013-11-08 03:58:48 +08:00
|
|
|
CC_SAFE_DELETE(ret);
|
2013-12-18 17:47:20 +08:00
|
|
|
return nullptr;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
2013-11-08 03:58:48 +08:00
|
|
|
TextFieldTTF * TextFieldTTF::textFieldWithPlaceHolder(const std::string& placeholder, const std::string& fontName, float fontSize)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-08 03:58:48 +08:00
|
|
|
TextFieldTTF *ret = new TextFieldTTF();
|
|
|
|
if(ret && ret->initWithString("", fontName, fontSize))
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-08 03:58:48 +08:00
|
|
|
ret->autorelease();
|
|
|
|
if (placeholder.size()>0)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-08 03:58:48 +08:00
|
|
|
ret->setPlaceHolder(placeholder);
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2013-11-08 03:58:48 +08:00
|
|
|
return ret;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2013-11-08 03:58:48 +08:00
|
|
|
CC_SAFE_DELETE(ret);
|
2013-12-18 17:47:20 +08:00
|
|
|
return nullptr;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// initialize
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2013-11-08 03:58:48 +08:00
|
|
|
bool TextFieldTTF::initWithPlaceHolder(const std::string& placeholder, const Size& dimensions, TextHAlignment alignment, const std::string& fontName, float fontSize)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-08 03:58:48 +08:00
|
|
|
_placeHolder = placeholder;
|
|
|
|
return LabelTTF::initWithString(_placeHolder, fontName, fontSize, dimensions, alignment);
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2013-11-08 03:58:48 +08:00
|
|
|
bool TextFieldTTF::initWithPlaceHolder(const std::string& placeholder, const std::string& fontName, float fontSize)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-08 03:58:48 +08:00
|
|
|
_placeHolder = std::string(placeholder);
|
|
|
|
return LabelTTF::initWithString(_placeHolder, fontName, fontSize);
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
2013-06-20 14:13:12 +08:00
|
|
|
// IMEDelegate
|
2012-04-19 14:35:52 +08:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
bool TextFieldTTF::attachWithIME()
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-12-18 17:47:20 +08:00
|
|
|
bool ret = IMEDelegate::attachWithIME();
|
|
|
|
if (ret)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
// open keyboard
|
2013-07-12 06:24:23 +08:00
|
|
|
EGLView * pGlView = Director::getInstance()->getOpenGLView();
|
2012-04-19 14:35:52 +08:00
|
|
|
if (pGlView)
|
|
|
|
{
|
|
|
|
pGlView->setIMEKeyboardState(true);
|
|
|
|
}
|
|
|
|
}
|
2013-12-18 17:47:20 +08:00
|
|
|
return ret;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
bool TextFieldTTF::detachWithIME()
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-12-18 17:47:20 +08:00
|
|
|
bool ret = IMEDelegate::detachWithIME();
|
|
|
|
if (ret)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
// close keyboard
|
2013-12-18 17:47:20 +08:00
|
|
|
EGLView * glView = Director::getInstance()->getOpenGLView();
|
|
|
|
if (glView)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-12-18 17:47:20 +08:00
|
|
|
glView->setIMEKeyboardState(false);
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
}
|
2013-12-18 17:47:20 +08:00
|
|
|
return ret;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
bool TextFieldTTF::canAttachWithIME()
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
return (_delegate) ? (! _delegate->onTextFieldAttachWithIME(this)) : true;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
bool TextFieldTTF::canDetachWithIME()
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
return (_delegate) ? (! _delegate->onTextFieldDetachWithIME(this)) : true;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void TextFieldTTF::insertText(const char * text, int len)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-12-18 17:47:20 +08:00
|
|
|
std::string insert(text, len);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
// insert \n means input end
|
2013-12-18 17:47:20 +08:00
|
|
|
int pos = static_cast<int>(insert.find('\n'));
|
|
|
|
if ((int)insert.npos != pos)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-12-18 17:47:20 +08:00
|
|
|
len = pos;
|
|
|
|
insert.erase(pos);
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2013-04-19 09:55:29 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
if (len > 0)
|
|
|
|
{
|
2013-12-18 17:47:20 +08:00
|
|
|
if (_delegate && _delegate->onTextFieldInsertText(this, insert.c_str(), len))
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2012-09-17 15:02:24 +08:00
|
|
|
// delegate doesn't want to insert text
|
2012-04-19 14:35:52 +08:00
|
|
|
return;
|
|
|
|
}
|
2013-04-19 09:55:29 +08:00
|
|
|
|
2013-12-18 17:47:20 +08:00
|
|
|
_charCount += _calcCharCount(insert.c_str());
|
2013-11-08 03:58:48 +08:00
|
|
|
std::string sText(_inputText);
|
2013-12-18 17:47:20 +08:00
|
|
|
sText.append(insert);
|
2013-11-08 03:58:48 +08:00
|
|
|
setString(sText);
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
2013-12-18 17:47:20 +08:00
|
|
|
if ((int)insert.npos == pos) {
|
2012-04-19 14:35:52 +08:00
|
|
|
return;
|
|
|
|
}
|
2013-04-19 09:55:29 +08:00
|
|
|
|
2012-09-17 15:02:24 +08:00
|
|
|
// '\n' inserted, let delegate process first
|
2013-06-15 14:03:30 +08:00
|
|
|
if (_delegate && _delegate->onTextFieldInsertText(this, "\n", 1))
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2013-04-19 09:55:29 +08:00
|
|
|
|
2012-09-17 15:02:24 +08:00
|
|
|
// if delegate hasn't processed, detach from IME by default
|
2012-04-19 14:35:52 +08:00
|
|
|
detachWithIME();
|
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void TextFieldTTF::deleteBackward()
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-12-18 17:47:20 +08:00
|
|
|
size_t len = _inputText.length();
|
|
|
|
if (! len)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
// there is no string
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get the delete byte number
|
2013-12-27 15:06:16 +08:00
|
|
|
size_t deleteLen = 1; // default, erase 1 byte
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-12-18 17:47:20 +08:00
|
|
|
while(0x80 == (0xC0 & _inputText.at(len - deleteLen)))
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-12-18 17:47:20 +08:00
|
|
|
++deleteLen;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
2013-12-18 17:47:20 +08:00
|
|
|
if (_delegate && _delegate->onTextFieldDeleteBackward(this, _inputText.c_str() + len - deleteLen, deleteLen))
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2012-09-17 15:02:24 +08:00
|
|
|
// delegate doesn't wan't to delete backwards
|
2012-04-19 14:35:52 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-09-17 15:02:24 +08:00
|
|
|
// if all text deleted, show placeholder string
|
2013-12-18 17:47:20 +08:00
|
|
|
if (len <= deleteLen)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-08 03:58:48 +08:00
|
|
|
_inputText = "";
|
2013-06-15 14:03:30 +08:00
|
|
|
_charCount = 0;
|
2013-11-08 03:58:48 +08:00
|
|
|
LabelTTF::setString(_placeHolder);
|
2012-04-19 14:35:52 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// set new input text
|
2013-12-18 17:47:20 +08:00
|
|
|
std::string text(_inputText.c_str(), len - deleteLen);
|
|
|
|
setString(text);
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
2013-12-24 15:49:58 +08:00
|
|
|
const std::string& TextFieldTTF::getContentText()
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-12-24 15:49:58 +08:00
|
|
|
return _inputText;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void TextFieldTTF::draw()
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
if (_delegate && _delegate->onDraw(this))
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2013-11-08 03:58:48 +08:00
|
|
|
if (_inputText.length())
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-06-20 14:13:12 +08:00
|
|
|
LabelTTF::draw();
|
2012-04-19 14:35:52 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// draw placeholder
|
2013-07-05 16:49:22 +08:00
|
|
|
Color3B color = getColor();
|
2013-06-15 14:03:30 +08:00
|
|
|
setColor(_colorSpaceHolder);
|
2013-06-20 14:13:12 +08:00
|
|
|
LabelTTF::draw();
|
2012-04-19 14:35:52 +08:00
|
|
|
setColor(color);
|
|
|
|
}
|
|
|
|
|
2013-07-05 16:49:22 +08:00
|
|
|
const Color3B& TextFieldTTF::getColorSpaceHolder()
|
2012-11-20 16:34:55 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
return _colorSpaceHolder;
|
2012-11-20 16:34:55 +08:00
|
|
|
}
|
|
|
|
|
2013-07-05 16:49:22 +08:00
|
|
|
void TextFieldTTF::setColorSpaceHolder(const Color3B& color)
|
2012-11-20 16:34:55 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_colorSpaceHolder = color;
|
2012-11-20 16:34:55 +08:00
|
|
|
}
|
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// properties
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// input text property
|
2013-11-08 03:58:48 +08:00
|
|
|
void TextFieldTTF::setString(const std::string &text)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-04-19 16:09:26 +08:00
|
|
|
static char bulletString[] = {(char)0xe2, (char)0x80, (char)0xa2, (char)0x00};
|
2013-04-19 09:55:29 +08:00
|
|
|
std::string displayText;
|
2013-12-06 16:32:06 +08:00
|
|
|
size_t length;
|
2013-04-19 09:55:29 +08:00
|
|
|
|
2013-11-08 03:58:48 +08:00
|
|
|
if (text.length()>0)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-08 03:58:48 +08:00
|
|
|
_inputText = text;
|
|
|
|
displayText = _inputText;
|
2013-06-15 14:03:30 +08:00
|
|
|
if (_secureTextEntry)
|
2013-04-19 09:55:29 +08:00
|
|
|
{
|
|
|
|
displayText = "";
|
2013-11-08 03:58:48 +08:00
|
|
|
length = _inputText.length();
|
2013-04-19 09:55:29 +08:00
|
|
|
while (length)
|
|
|
|
{
|
|
|
|
displayText.append(bulletString);
|
|
|
|
--length;
|
|
|
|
}
|
|
|
|
}
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-11-08 03:58:48 +08:00
|
|
|
_inputText = "";
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// if there is no input text, display placeholder instead
|
2013-11-08 03:58:48 +08:00
|
|
|
if (! _inputText.length())
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-08 03:58:48 +08:00
|
|
|
LabelTTF::setString(_placeHolder);
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-11-08 03:58:48 +08:00
|
|
|
LabelTTF::setString(displayText);
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2013-11-08 03:58:48 +08:00
|
|
|
_charCount = _calcCharCount(_inputText.c_str());
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
2013-11-08 04:42:16 +08:00
|
|
|
const std::string& TextFieldTTF::getString() const
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-08 04:42:16 +08:00
|
|
|
return _inputText;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// place holder text property
|
2013-11-08 03:58:48 +08:00
|
|
|
void TextFieldTTF::setPlaceHolder(const std::string& text)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-08 03:58:48 +08:00
|
|
|
_placeHolder = text;
|
|
|
|
if (! _inputText.length())
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-08 03:58:48 +08:00
|
|
|
LabelTTF::setString(_placeHolder);
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-08 03:58:48 +08:00
|
|
|
const std::string& TextFieldTTF::getPlaceHolder() const
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-08 03:58:48 +08:00
|
|
|
return _placeHolder;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
2013-03-28 22:08:33 +08:00
|
|
|
// secureTextEntry
|
2013-06-20 14:13:12 +08:00
|
|
|
void TextFieldTTF::setSecureTextEntry(bool value)
|
2013-03-28 22:08:33 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
if (_secureTextEntry != value)
|
2013-04-19 09:55:29 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_secureTextEntry = value;
|
2013-04-19 09:55:29 +08:00
|
|
|
setString(getString());
|
|
|
|
}
|
2013-03-28 22:08:33 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
bool TextFieldTTF::isSecureTextEntry()
|
2013-03-28 22:08:33 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
return _secureTextEntry;
|
2013-03-28 22:08:33 +08:00
|
|
|
}
|
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
NS_CC_END
|