FIFE 2008.0
utf8textbox.cpp
00001 /***************************************************************************
00002  *   Copyright (C) 2009 by the FIFE team                                   *
00003  *   http://www.fifengine.de                                               *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 // Standard C++ library includes
00023 #include <cassert>
00024 
00025 // 3rd party library includes
00026 
00027 // FIFE includes
00028 // These includes are split up in two parts, separated by one empty line
00029 // First block: files included from the FIFE root src directory
00030 // Second block: files included from the same folder
00031 #include "util/utf8/utf8.h"
00032 
00033 #include "utf8textbox.h"
00034 
00035 namespace gcn {
00036 
00037     UTF8TextBox::UTF8TextBox(const std::string & text)
00038         :TextBox(text), mStringEditor(new UTF8StringEditor())
00039     {
00040     }
00041 
00042     UTF8TextBox::~ UTF8TextBox()
00043     {
00044         delete mStringEditor;
00045     }
00046 
00047     void UTF8TextBox::keyPressed(KeyEvent& keyEvent)
00048     {
00049         Key key = keyEvent.getKey();
00050 
00051         if (key.getValue() == Key::LEFT)
00052         {
00053             if (mCaretColumn == 0)
00054             {
00055                 if (mCaretRow > 0)
00056                 {
00057                     mCaretRow--;
00058                     mCaretColumn = mTextRows[mCaretRow].size();
00059                 }
00060             }
00061             else
00062             {
00063                 mCaretColumn = mStringEditor->prevChar(mTextRows[mCaretRow], mCaretColumn);
00064             }
00065         }
00066         else if (key.getValue() == Key::RIGHT)
00067         {
00068             if (mCaretColumn < mTextRows[mCaretRow].size())
00069             {
00070                 mCaretColumn = mStringEditor->nextChar(mTextRows[mCaretRow], mCaretColumn);
00071             }
00072             else
00073             {
00074                 if (mCaretRow < mTextRows.size() - 1)
00075                 {
00076                     mCaretRow++;
00077                     mCaretColumn = 0;
00078                 }
00079             }
00080         }
00081         else if (key.getValue() == Key::DOWN)
00082         {
00083             setCaretRowUTF8(mCaretRow + 1);
00084         }
00085 
00086         else if (key.getValue() == Key::UP)
00087         {
00088             setCaretRowUTF8(mCaretRow - 1);
00089         }
00090 
00091         else if (key.getValue() == Key::HOME)
00092         {
00093             mCaretColumn = 0;
00094         }
00095 
00096         else if (key.getValue() == Key::END)
00097         {
00098             mCaretColumn = mTextRows[mCaretRow].size();
00099         }
00100 
00101         else if (key.getValue() == Key::ENTER && mEditable)
00102         {
00103             mTextRows.insert(mTextRows.begin() + mCaretRow + 1,
00104                                 mTextRows[mCaretRow].substr(mCaretColumn, mTextRows[mCaretRow].size() - mCaretColumn));
00105             mTextRows[mCaretRow].resize(mCaretColumn);
00106             ++mCaretRow;
00107             mCaretColumn = 0;
00108         }
00109 
00110         else if (key.getValue() == Key::BACKSPACE
00111                     && mCaretColumn != 0
00112                     && mEditable)
00113         {
00114             mCaretColumn = mStringEditor->prevChar(mTextRows[mCaretRow], mCaretColumn);
00115             mCaretColumn = mStringEditor->eraseChar(mTextRows[mCaretRow], mCaretColumn);
00116         }
00117 
00118         else if (key.getValue() == Key::BACKSPACE
00119                     && mCaretColumn == 0
00120                     && mCaretRow != 0
00121                     && mEditable)
00122         {
00123             mCaretColumn = mTextRows[mCaretRow - 1].size();
00124             mTextRows[mCaretRow - 1] += mTextRows[mCaretRow];
00125             mTextRows.erase(mTextRows.begin() + mCaretRow);
00126             mCaretRow--;
00127         }
00128 
00129         else if (key.getValue() == Key::DELETE
00130                     && mCaretColumn < (int)mTextRows[mCaretRow].size()
00131                     && mEditable)
00132         {
00133             mCaretColumn = mStringEditor->eraseChar(mTextRows[mCaretRow], mCaretColumn);
00134         }
00135 
00136         else if (key.getValue() == Key::DELETE
00137                     && mCaretColumn == (int)mTextRows[mCaretRow].size()
00138                     && mCaretRow < ((int)mTextRows.size() - 1)
00139                     && mEditable)
00140         {
00141             mTextRows[mCaretRow] += mTextRows[mCaretRow + 1];
00142             mTextRows.erase(mTextRows.begin() + mCaretRow + 1);
00143         }
00144 
00145         else if(key.getValue() == Key::PAGE_UP)
00146         {
00147             Widget* par = getParent();
00148 
00149             if (par != NULL)
00150             {
00151                 int rowsPerPage = par->getChildrenArea().height / getFont()->getHeight();
00152                 int chars = mStringEditor->countChars(mTextRows[mCaretRow], mCaretColumn);
00153                 mCaretRow -= rowsPerPage;
00154 
00155                 if (mCaretRow < 0)
00156                 {
00157                     mCaretRow = 0;
00158                 }
00159                 mCaretColumn = mStringEditor->getOffset(mTextRows[mCaretRow], chars);
00160             }
00161         }
00162 
00163         else if(key.getValue() == Key::PAGE_DOWN)
00164         {
00165             Widget* par = getParent();
00166 
00167             if (par != NULL)
00168             {
00169                 int rowsPerPage = par->getChildrenArea().height / getFont()->getHeight();
00170                 int chars = mStringEditor->countChars(mTextRows[mCaretRow], mCaretColumn);
00171                 mCaretRow += rowsPerPage;
00172 
00173                 if (mCaretRow >= (int)mTextRows.size())
00174                 {
00175                     mCaretRow = mTextRows.size() - 1;
00176                 }
00177 
00178                 mCaretColumn = mStringEditor->getOffset(mTextRows[mCaretRow], chars);
00179             }
00180         }
00181 
00182         else if(key.getValue() == Key::TAB
00183                 && mEditable)
00184         {
00185             // FIXME: jump X spaces, so mCaretColumn % TAB_SIZE = 0 and X <= TAB_SIZE
00186             mTextRows[mCaretRow].insert(mCaretColumn,std::string("    "));
00187             mCaretColumn += 4;
00188         }
00189 
00190         else if ((key.isCharacter() || key.getValue() > 255)
00191                     && mEditable)
00192         {
00193             mCaretColumn = mStringEditor->insertChar(mTextRows[mCaretRow], mCaretColumn, key.getValue());
00194         }
00195 
00196         adjustSize();
00197         scrollToCaret();
00198         assert( utf8::is_valid(mTextRows[mCaretRow].begin(),mTextRows[mCaretRow].end()) );
00199         assert( utf8::is_valid(mTextRows[mCaretRow].begin(),mTextRows[mCaretRow].begin() + mCaretColumn) );
00200         keyEvent.consume();
00201     }
00202 
00203 
00204     void UTF8TextBox::setCaretColumnUTF8(int column)
00205     {
00206         // no need to clip the column, mStringEditor handles it automaticly
00207         mCaretColumn = mStringEditor->getOffset(mTextRows[mCaretRow], column);
00208     }
00209 
00210     void UTF8TextBox::setCaretRowUTF8(int row)
00211     {
00212         int chars = mStringEditor->countChars(mTextRows[mCaretRow], mCaretColumn);
00213         if (row < 0) {
00214             row = 0;
00215         } else if (row >= mTextRows.size()) {
00216             row = mTextRows.size() - 1;
00217         }
00218         mCaretRow = row;
00219         mCaretColumn = mStringEditor->getOffset(mTextRows[mCaretRow], chars);
00220     }
00221 
00222 }
00223 
00224 
 All Classes Namespaces Functions Variables Enumerations Enumerator