diff options
author | Guillaume Melquiond <guillaume.melquiond@gmail.com> | 2007-09-20 22:17:21 +0000 |
---|---|---|
committer | Ira Rice <irarice@gmail.com> | 2009-01-06 15:13:31 -0700 |
commit | 57b4d184f8c47c853ca49ffb56f99c0533c71d07 (patch) | |
tree | 54a11279aee22c6da542f02cc772086aa7b6c27f /src/gui/textfield.cpp | |
parent | ea50de0b56063f3e7c6436422d275ac6e71d0072 (diff) | |
download | mana-57b4d184f8c47c853ca49ffb56f99c0533c71d07.tar.gz mana-57b4d184f8c47c853ca49ffb56f99c0533c71d07.tar.bz2 mana-57b4d184f8c47c853ca49ffb56f99c0533c71d07.tar.xz mana-57b4d184f8c47c853ca49ffb56f99c0533c71d07.zip |
Added support for unicode charset in textfields and chat.
Conflicts:
src/Makefile.am
src/game.cpp
src/gui/browserbox.cpp
src/gui/gui.cpp
src/gui/textfield.cpp
src/main.cpp
(cherry picked from mainline commit 7b67e852086ad3ccd98a622f890b245ab6a0a321)
Diffstat (limited to 'src/gui/textfield.cpp')
-rw-r--r-- | src/gui/textfield.cpp | 129 |
1 files changed, 101 insertions, 28 deletions
diff --git a/src/gui/textfield.cpp b/src/gui/textfield.cpp index bd016a8d..d4709d3f 100644 --- a/src/gui/textfield.cpp +++ b/src/gui/textfield.cpp @@ -19,12 +19,15 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "textfield.h" + #include <algorithm> #include <guichan/font.hpp> #include <guichan/sdl/sdlinput.hpp> +#include "sdlinput.h" #include "textfield.h" #include "../graphics.h" @@ -34,6 +37,8 @@ #include "../utils/dtor.h" +#undef DELETE //Win32 compatibility hack + int TextField::instances = 0; ImageRect TextField::skin; @@ -123,34 +128,6 @@ void TextField::setNumeric(bool numeric) } } -void TextField::keyPressed(gcn::KeyEvent &keyEvent) -{ - if (mNumeric) - { - while (true) - { - const gcn::Key &key = keyEvent.getKey(); - if (key.isNumber()) - { - break; - } - int value = key.getValue(); - if (value == SDLK_LEFT || value == SDLK_RIGHT || - value == SDLK_HOME || value == SDLK_END || - value == SDLK_BACKSPACE || value == SDLK_DELETE) - { - break; - } - return; - } - } - gcn::TextField::keyPressed(keyEvent); - if (mListener) - { - mListener->listen(this); - } -} - int TextField::getValue() const { if (!mNumeric) @@ -168,3 +145,99 @@ int TextField::getValue() const } return value; } + +void TextField::keyPressed(gcn::KeyEvent &keyEvent) +{ + int val = keyEvent.getKey().getValue(); + + if (val >= 32) + { + int l; + if (val < 128) l = 1; // 0xxxxxxx + else if (val < 0x800) l = 2; // 110xxxxx 10xxxxxx + else if (val < 0x10000) l = 3; // 1110xxxx 10xxxxxx 10xxxxxx + else l = 4; // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + + char buf[4]; + for (int i = 0; i < l; ++i) + { + buf[i] = val >> (6 * (l - i - 1)); + if (i > 0) buf[i] = (buf[i] & 63) | 128; + } + + if (l > 1) buf[0] |= 255 << (8 - l); + + mText.insert(mCaretPosition, std::string(buf, buf + l)); + mCaretPosition += l; + } + + /* In UTF-8, 10xxxxxx is only used for inner parts of characters. So skip + them when processing key presses. */ + + switch (val) + { + case Key::LEFT: + { + while (mCaretPosition > 0) + { + --mCaretPosition; + if ((mText[mCaretPosition] & 192) != 128) + break; + } + } break; + + case Key::RIGHT: + { + unsigned sz = mText.size(); + while (mCaretPosition < sz) + { + ++mCaretPosition; + if (mCaretPosition == sz || + (mText[mCaretPosition] & 192) != 128) + break; + } + } break; + + case Key::DELETE: + { + unsigned sz = mText.size(); + while (mCaretPosition < sz) + { + --sz; + mText.erase(mCaretPosition, 1); + if (mCaretPosition == sz || + (mText[mCaretPosition] & 192) != 128) + break; + } + } break; + + case Key::BACKSPACE: + { + while (mCaretPosition > 0) + { + --mCaretPosition; + int v = mText[mCaretPosition]; + mText.erase(mCaretPosition, 1); + if ((v & 192) != 128) break; + } + } break; + + case Key::ENTER: + distributeActionEvent(); + break; + + case Key::HOME: + mCaretPosition = 0; + break; + + case Key::END: + mCaretPosition = mText.size(); + break; + + case Key::TAB: + return; + } + + keyEvent.consume(); + fixScroll(); +} |