|
|
@@ -105,209 +105,206 @@ bool TextBox::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int conta
|
|
|
|
|
|
bool TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
|
|
|
{
|
|
|
- if (isInFocus())
|
|
|
+ switch (evt)
|
|
|
{
|
|
|
- switch (evt)
|
|
|
+ case Keyboard::KEY_PRESS:
|
|
|
{
|
|
|
- case Keyboard::KEY_PRESS:
|
|
|
+ switch (key)
|
|
|
{
|
|
|
- switch (key)
|
|
|
+ case Keyboard::KEY_HOME:
|
|
|
{
|
|
|
- case Keyboard::KEY_HOME:
|
|
|
- {
|
|
|
- // TODO: Move cursor to beginning of line.
|
|
|
- // This only works for left alignment...
|
|
|
+ // TODO: Move cursor to beginning of line.
|
|
|
+ // This only works for left alignment...
|
|
|
|
|
|
- //_caretLocation.x = _viewportClipBounds.x;
|
|
|
- //_dirty = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- case Keyboard::KEY_END:
|
|
|
- {
|
|
|
- // TODO: Move cursor to end of line.
|
|
|
- break;
|
|
|
- }
|
|
|
- case Keyboard::KEY_DELETE:
|
|
|
- {
|
|
|
- Font* font = getFont(_state);
|
|
|
- GP_ASSERT(font);
|
|
|
- unsigned int fontSize = getFontSize(_state);
|
|
|
- Font::Justify textAlignment = getTextAlignment(_state);
|
|
|
- bool rightToLeft = getTextRightToLeft(_state);
|
|
|
+ //_caretLocation.x = _viewportClipBounds.x;
|
|
|
+ //_dirty = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case Keyboard::KEY_END:
|
|
|
+ {
|
|
|
+ // TODO: Move cursor to end of line.
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case Keyboard::KEY_DELETE:
|
|
|
+ {
|
|
|
+ Font* font = getFont(_state);
|
|
|
+ GP_ASSERT(font);
|
|
|
+ unsigned int fontSize = getFontSize(_state);
|
|
|
+ Font::Justify textAlignment = getTextAlignment(_state);
|
|
|
+ bool rightToLeft = getTextRightToLeft(_state);
|
|
|
|
|
|
- int textIndex = font->getIndexAtLocation(_text.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
|
|
|
- textAlignment, true, rightToLeft);
|
|
|
+ int textIndex = font->getIndexAtLocation(_text.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
|
|
|
+ textAlignment, true, rightToLeft);
|
|
|
|
|
|
- _text.erase(textIndex, 1);
|
|
|
- font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
|
|
|
- textAlignment, true, rightToLeft);
|
|
|
- _dirty = true;
|
|
|
- notifyListeners(Control::Listener::TEXT_CHANGED);
|
|
|
- break;
|
|
|
- }
|
|
|
- case Keyboard::KEY_LEFT_ARROW:
|
|
|
- {
|
|
|
- Font* font = getFont(_state);
|
|
|
- GP_ASSERT(font);
|
|
|
- unsigned int fontSize = getFontSize(_state);
|
|
|
- Font::Justify textAlignment = getTextAlignment(_state);
|
|
|
- bool rightToLeft = getTextRightToLeft(_state);
|
|
|
+ _text.erase(textIndex, 1);
|
|
|
+ font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
|
|
|
+ textAlignment, true, rightToLeft);
|
|
|
+ _dirty = true;
|
|
|
+ notifyListeners(Control::Listener::TEXT_CHANGED);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case Keyboard::KEY_LEFT_ARROW:
|
|
|
+ {
|
|
|
+ Font* font = getFont(_state);
|
|
|
+ GP_ASSERT(font);
|
|
|
+ unsigned int fontSize = getFontSize(_state);
|
|
|
+ Font::Justify textAlignment = getTextAlignment(_state);
|
|
|
+ bool rightToLeft = getTextRightToLeft(_state);
|
|
|
|
|
|
- int textIndex = font->getIndexAtLocation(_text.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
|
|
|
- textAlignment, true, rightToLeft);
|
|
|
- font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex - 1,
|
|
|
- textAlignment, true, rightToLeft);
|
|
|
- _dirty = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- case Keyboard::KEY_RIGHT_ARROW:
|
|
|
- {
|
|
|
- Font* font = getFont(_state);
|
|
|
- GP_ASSERT(font);
|
|
|
- unsigned int fontSize = getFontSize(_state);
|
|
|
- Font::Justify textAlignment = getTextAlignment(_state);
|
|
|
- bool rightToLeft = getTextRightToLeft(_state);
|
|
|
+ int textIndex = font->getIndexAtLocation(_text.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
|
|
|
+ textAlignment, true, rightToLeft);
|
|
|
+ font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex - 1,
|
|
|
+ textAlignment, true, rightToLeft);
|
|
|
+ _dirty = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case Keyboard::KEY_RIGHT_ARROW:
|
|
|
+ {
|
|
|
+ Font* font = getFont(_state);
|
|
|
+ GP_ASSERT(font);
|
|
|
+ unsigned int fontSize = getFontSize(_state);
|
|
|
+ Font::Justify textAlignment = getTextAlignment(_state);
|
|
|
+ bool rightToLeft = getTextRightToLeft(_state);
|
|
|
|
|
|
- int textIndex = font->getIndexAtLocation(_text.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
|
|
|
- textAlignment, true, rightToLeft);
|
|
|
- font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex + 1,
|
|
|
- textAlignment, true, rightToLeft);
|
|
|
- _dirty = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- case Keyboard::KEY_UP_ARROW:
|
|
|
+ int textIndex = font->getIndexAtLocation(_text.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
|
|
|
+ textAlignment, true, rightToLeft);
|
|
|
+ font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex + 1,
|
|
|
+ textAlignment, true, rightToLeft);
|
|
|
+ _dirty = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case Keyboard::KEY_UP_ARROW:
|
|
|
+ {
|
|
|
+ Font* font = getFont(_state);
|
|
|
+ GP_ASSERT(font);
|
|
|
+ unsigned int fontSize = getFontSize(_state);
|
|
|
+ Font::Justify textAlignment = getTextAlignment(_state);
|
|
|
+ bool rightToLeft = getTextRightToLeft(_state);
|
|
|
+ _prevCaretLocation.set(_caretLocation);
|
|
|
+ _caretLocation.y -= fontSize;
|
|
|
+ int textIndex = font->getIndexAtLocation(_text.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
|
|
|
+ textAlignment, true, rightToLeft);
|
|
|
+ if (textIndex == -1)
|
|
|
{
|
|
|
- Font* font = getFont(_state);
|
|
|
- GP_ASSERT(font);
|
|
|
- unsigned int fontSize = getFontSize(_state);
|
|
|
- Font::Justify textAlignment = getTextAlignment(_state);
|
|
|
- bool rightToLeft = getTextRightToLeft(_state);
|
|
|
- _prevCaretLocation.set(_caretLocation);
|
|
|
- _caretLocation.y -= fontSize;
|
|
|
- int textIndex = font->getIndexAtLocation(_text.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
|
|
|
- textAlignment, true, rightToLeft);
|
|
|
- if (textIndex == -1)
|
|
|
- {
|
|
|
- _caretLocation.set(_prevCaretLocation);
|
|
|
- }
|
|
|
-
|
|
|
- _dirty = true;
|
|
|
- break;
|
|
|
+ _caretLocation.set(_prevCaretLocation);
|
|
|
}
|
|
|
- case Keyboard::KEY_DOWN_ARROW:
|
|
|
- {
|
|
|
- Font* font = getFont(_state);
|
|
|
- GP_ASSERT(font);
|
|
|
- unsigned int fontSize = getFontSize(_state);
|
|
|
- Font::Justify textAlignment = getTextAlignment(_state);
|
|
|
- bool rightToLeft = getTextRightToLeft(_state);
|
|
|
- _prevCaretLocation.set(_caretLocation);
|
|
|
- _caretLocation.y += fontSize;
|
|
|
- int textIndex = font->getIndexAtLocation(_text.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
|
|
|
- textAlignment, true, rightToLeft);
|
|
|
- if (textIndex == -1)
|
|
|
- {
|
|
|
- _caretLocation.set(_prevCaretLocation);
|
|
|
- }
|
|
|
|
|
|
- _dirty = true;
|
|
|
- break;
|
|
|
+ _dirty = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case Keyboard::KEY_DOWN_ARROW:
|
|
|
+ {
|
|
|
+ Font* font = getFont(_state);
|
|
|
+ GP_ASSERT(font);
|
|
|
+ unsigned int fontSize = getFontSize(_state);
|
|
|
+ Font::Justify textAlignment = getTextAlignment(_state);
|
|
|
+ bool rightToLeft = getTextRightToLeft(_state);
|
|
|
+ _prevCaretLocation.set(_caretLocation);
|
|
|
+ _caretLocation.y += fontSize;
|
|
|
+ int textIndex = font->getIndexAtLocation(_text.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
|
|
|
+ textAlignment, true, rightToLeft);
|
|
|
+ if (textIndex == -1)
|
|
|
+ {
|
|
|
+ _caretLocation.set(_prevCaretLocation);
|
|
|
}
|
|
|
+
|
|
|
+ _dirty = true;
|
|
|
+ break;
|
|
|
}
|
|
|
- break;
|
|
|
}
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- case Keyboard::KEY_CHAR:
|
|
|
- {
|
|
|
- Font* font = getFont(_state);
|
|
|
- GP_ASSERT(font);
|
|
|
- unsigned int fontSize = getFontSize(_state);
|
|
|
- Font::Justify textAlignment = getTextAlignment(_state);
|
|
|
- bool rightToLeft = getTextRightToLeft(_state);
|
|
|
+ case Keyboard::KEY_CHAR:
|
|
|
+ {
|
|
|
+ Font* font = getFont(_state);
|
|
|
+ GP_ASSERT(font);
|
|
|
+ unsigned int fontSize = getFontSize(_state);
|
|
|
+ Font::Justify textAlignment = getTextAlignment(_state);
|
|
|
+ bool rightToLeft = getTextRightToLeft(_state);
|
|
|
|
|
|
- int textIndex = font->getIndexAtLocation(_text.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
|
|
|
+ int textIndex = font->getIndexAtLocation(_text.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
|
|
|
+ textAlignment, true, rightToLeft);
|
|
|
+ if (textIndex == -1)
|
|
|
+ {
|
|
|
+ textIndex = 0;
|
|
|
+ font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, 0,
|
|
|
textAlignment, true, rightToLeft);
|
|
|
- if (textIndex == -1)
|
|
|
- {
|
|
|
- textIndex = 0;
|
|
|
- font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, 0,
|
|
|
- textAlignment, true, rightToLeft);
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- switch (key)
|
|
|
+ switch (key)
|
|
|
+ {
|
|
|
+ case Keyboard::KEY_BACKSPACE:
|
|
|
{
|
|
|
- case Keyboard::KEY_BACKSPACE:
|
|
|
+ if (textIndex > 0)
|
|
|
{
|
|
|
- if (textIndex > 0)
|
|
|
- {
|
|
|
- --textIndex;
|
|
|
- _text.erase(textIndex, 1);
|
|
|
- font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
|
|
|
- textAlignment, true, rightToLeft);
|
|
|
+ --textIndex;
|
|
|
+ _text.erase(textIndex, 1);
|
|
|
+ font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
|
|
|
+ textAlignment, true, rightToLeft);
|
|
|
|
|
|
- _dirty = true;
|
|
|
- }
|
|
|
- break;
|
|
|
+ _dirty = true;
|
|
|
}
|
|
|
- case Keyboard::KEY_RETURN:
|
|
|
- // TODO: Handle line-break insertion correctly.
|
|
|
- break;
|
|
|
- case Keyboard::KEY_ESCAPE:
|
|
|
- break;
|
|
|
- case Keyboard::KEY_TAB:
|
|
|
- // Allow tab to move the focus forward.
|
|
|
- return false;
|
|
|
- break;
|
|
|
- default:
|
|
|
- {
|
|
|
- // Insert character into string.
|
|
|
- _text.insert(textIndex, 1, (char)key);
|
|
|
-
|
|
|
- // Get new location of caret.
|
|
|
- font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex + 1,
|
|
|
- textAlignment, true, rightToLeft);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case Keyboard::KEY_RETURN:
|
|
|
+ // TODO: Handle line-break insertion correctly.
|
|
|
+ break;
|
|
|
+ case Keyboard::KEY_ESCAPE:
|
|
|
+ break;
|
|
|
+ case Keyboard::KEY_TAB:
|
|
|
+ // Allow tab to move the focus forward.
|
|
|
+ return false;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ {
|
|
|
+ // Insert character into string.
|
|
|
+ _text.insert(textIndex, 1, (char)key);
|
|
|
|
|
|
- if (key == ' ')
|
|
|
- {
|
|
|
- // If a space was entered, check that caret is still within bounds.
|
|
|
- if (_caretLocation.x >= _textBounds.x + _textBounds.width ||
|
|
|
- _caretLocation.y >= _textBounds.y + _textBounds.height)
|
|
|
- {
|
|
|
- // If not, undo the character insertion.
|
|
|
- _text.erase(textIndex, 1);
|
|
|
- font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
|
|
|
- textAlignment, true, rightToLeft);
|
|
|
-
|
|
|
- // No need to check again.
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
+ // Get new location of caret.
|
|
|
+ font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex + 1,
|
|
|
+ textAlignment, true, rightToLeft);
|
|
|
|
|
|
- // Always check that the text still fits within the clip region.
|
|
|
- Rectangle textBounds;
|
|
|
- font->measureText(_text.c_str(), _textBounds, fontSize, &textBounds, textAlignment, true, true);
|
|
|
- if (textBounds.x < _textBounds.x || textBounds.y < _textBounds.y ||
|
|
|
- textBounds.width >= _textBounds.width || textBounds.height >= _textBounds.height)
|
|
|
+ if (key == ' ')
|
|
|
+ {
|
|
|
+ // If a space was entered, check that caret is still within bounds.
|
|
|
+ if (_caretLocation.x >= _textBounds.x + _textBounds.width ||
|
|
|
+ _caretLocation.y >= _textBounds.y + _textBounds.height)
|
|
|
{
|
|
|
// If not, undo the character insertion.
|
|
|
_text.erase(textIndex, 1);
|
|
|
font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
|
|
|
textAlignment, true, rightToLeft);
|
|
|
|
|
|
- // TextBox is not dirty.
|
|
|
+ // No need to check again.
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
- _dirty = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Always check that the text still fits within the clip region.
|
|
|
+ Rectangle textBounds;
|
|
|
+ font->measureText(_text.c_str(), _textBounds, fontSize, &textBounds, textAlignment, true, true);
|
|
|
+ if (textBounds.x < _textBounds.x || textBounds.y < _textBounds.y ||
|
|
|
+ textBounds.width >= _textBounds.width || textBounds.height >= _textBounds.height)
|
|
|
+ {
|
|
|
+ // If not, undo the character insertion.
|
|
|
+ _text.erase(textIndex, 1);
|
|
|
+ font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
|
|
|
+ textAlignment, true, rightToLeft);
|
|
|
+
|
|
|
+ // TextBox is not dirty.
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ _dirty = true;
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
- notifyListeners(Control::Listener::TEXT_CHANGED);
|
|
|
+
|
|
|
break;
|
|
|
}
|
|
|
+
|
|
|
+ notifyListeners(Control::Listener::TEXT_CHANGED);
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -326,7 +323,7 @@ void TextBox::update(const Control* container, const Vector2& offset)
|
|
|
|
|
|
void TextBox::drawImages(SpriteBatch* spriteBatch, const Rectangle& clip)
|
|
|
{
|
|
|
- if (_caretImage && (_state == ACTIVE || isInFocus()))
|
|
|
+ if (_caretImage && (_state == ACTIVE || hasFocus()))
|
|
|
{
|
|
|
// Draw the cursor at its current location.
|
|
|
const Rectangle& region = _caretImage->getRegion();
|