FIFE  2008.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
utf8textbox.cpp
1 /***************************************************************************
2  * Copyright (C) 2009 by the FIFE team *
3  * http://www.fifengine.de *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 // Standard C++ library includes
23 #include <cassert>
24 
25 // 3rd party library includes
26 
27 // FIFE includes
28 // These includes are split up in two parts, separated by one empty line
29 // First block: files included from the FIFE root src directory
30 // Second block: files included from the same folder
31 #include "util/utf8/utf8.h"
32 
33 #include "utf8textbox.h"
34 
35 namespace gcn {
36 
37  UTF8TextBox::UTF8TextBox(const std::string & text)
38  :TextBox(text), mStringEditor(new UTF8StringEditor())
39  {
40  }
41 
43  {
44  delete mStringEditor;
45  }
46 
47  void UTF8TextBox::keyPressed(KeyEvent& keyEvent)
48  {
49  Key key = keyEvent.getKey();
50 
51  if (key.getValue() == Key::LEFT)
52  {
53  if (mCaretColumn == 0)
54  {
55  if (mCaretRow > 0)
56  {
57  mCaretRow--;
58  mCaretColumn = mTextRows[mCaretRow].size();
59  }
60  }
61  else
62  {
63  mCaretColumn = mStringEditor->prevChar(mTextRows[mCaretRow], mCaretColumn);
64  }
65  }
66  else if (key.getValue() == Key::RIGHT)
67  {
68  if (mCaretColumn < mTextRows[mCaretRow].size())
69  {
70  mCaretColumn = mStringEditor->nextChar(mTextRows[mCaretRow], mCaretColumn);
71  }
72  else
73  {
74  if (mCaretRow < mTextRows.size() - 1)
75  {
76  mCaretRow++;
77  mCaretColumn = 0;
78  }
79  }
80  }
81  else if (key.getValue() == Key::DOWN)
82  {
83  setCaretRowUTF8(mCaretRow + 1);
84  }
85 
86  else if (key.getValue() == Key::UP)
87  {
88  setCaretRowUTF8(mCaretRow - 1);
89  }
90 
91  else if (key.getValue() == Key::HOME)
92  {
93  mCaretColumn = 0;
94  }
95 
96  else if (key.getValue() == Key::END)
97  {
98  mCaretColumn = mTextRows[mCaretRow].size();
99  }
100 
101  else if (key.getValue() == Key::ENTER && mEditable)
102  {
103  mTextRows.insert(mTextRows.begin() + mCaretRow + 1,
104  mTextRows[mCaretRow].substr(mCaretColumn, mTextRows[mCaretRow].size() - mCaretColumn));
105  mTextRows[mCaretRow].resize(mCaretColumn);
106  ++mCaretRow;
107  mCaretColumn = 0;
108  }
109 
110  else if (key.getValue() == Key::BACKSPACE
111  && mCaretColumn != 0
112  && mEditable)
113  {
114  mCaretColumn = mStringEditor->prevChar(mTextRows[mCaretRow], mCaretColumn);
115  mCaretColumn = mStringEditor->eraseChar(mTextRows[mCaretRow], mCaretColumn);
116  }
117 
118  else if (key.getValue() == Key::BACKSPACE
119  && mCaretColumn == 0
120  && mCaretRow != 0
121  && mEditable)
122  {
123  mCaretColumn = mTextRows[mCaretRow - 1].size();
124  mTextRows[mCaretRow - 1] += mTextRows[mCaretRow];
125  mTextRows.erase(mTextRows.begin() + mCaretRow);
126  mCaretRow--;
127  }
128 
129  else if (key.getValue() == Key::DELETE
130  && mCaretColumn < (int)mTextRows[mCaretRow].size()
131  && mEditable)
132  {
133  mCaretColumn = mStringEditor->eraseChar(mTextRows[mCaretRow], mCaretColumn);
134  }
135 
136  else if (key.getValue() == Key::DELETE
137  && mCaretColumn == (int)mTextRows[mCaretRow].size()
138  && mCaretRow < ((int)mTextRows.size() - 1)
139  && mEditable)
140  {
141  mTextRows[mCaretRow] += mTextRows[mCaretRow + 1];
142  mTextRows.erase(mTextRows.begin() + mCaretRow + 1);
143  }
144 
145  else if(key.getValue() == Key::PAGE_UP)
146  {
147  Widget* par = getParent();
148 
149  if (par != NULL)
150  {
151  int rowsPerPage = par->getChildrenArea().height / getFont()->getHeight();
152  int chars = mStringEditor->countChars(mTextRows[mCaretRow], mCaretColumn);
153  mCaretRow -= rowsPerPage;
154 
155  if (mCaretRow < 0)
156  {
157  mCaretRow = 0;
158  }
159  mCaretColumn = mStringEditor->getOffset(mTextRows[mCaretRow], chars);
160  }
161  }
162 
163  else if(key.getValue() == Key::PAGE_DOWN)
164  {
165  Widget* par = getParent();
166 
167  if (par != NULL)
168  {
169  int rowsPerPage = par->getChildrenArea().height / getFont()->getHeight();
170  int chars = mStringEditor->countChars(mTextRows[mCaretRow], mCaretColumn);
171  mCaretRow += rowsPerPage;
172 
173  if (mCaretRow >= (int)mTextRows.size())
174  {
175  mCaretRow = mTextRows.size() - 1;
176  }
177 
178  mCaretColumn = mStringEditor->getOffset(mTextRows[mCaretRow], chars);
179  }
180  }
181 
182  else if(key.getValue() == Key::TAB
183  && mEditable)
184  {
185  // FIXME: jump X spaces, so mCaretColumn % TAB_SIZE = 0 and X <= TAB_SIZE
186  mTextRows[mCaretRow].insert(mCaretColumn,std::string(" "));
187  mCaretColumn += 4;
188  }
189 
190  else if ((key.isCharacter() || key.getValue() > 255)
191  && mEditable)
192  {
193  mCaretColumn = mStringEditor->insertChar(mTextRows[mCaretRow], mCaretColumn, key.getValue());
194  }
195 
196  adjustSize();
197  scrollToCaret();
198  assert( utf8::is_valid(mTextRows[mCaretRow].begin(),mTextRows[mCaretRow].end()) );
199  assert( utf8::is_valid(mTextRows[mCaretRow].begin(),mTextRows[mCaretRow].begin() + mCaretColumn) );
200  keyEvent.consume();
201  }
202 
203 
205  {
206  // no need to clip the column, mStringEditor handles it automaticly
207  mCaretColumn = mStringEditor->getOffset(mTextRows[mCaretRow], column);
208  }
209 
211  {
212  int chars = mStringEditor->countChars(mTextRows[mCaretRow], mCaretColumn);
213  if (row < 0) {
214  row = 0;
215  } else if (row >= mTextRows.size()) {
216  row = mTextRows.size() - 1;
217  }
218  mCaretRow = row;
219  mCaretColumn = mStringEditor->getOffset(mTextRows[mCaretRow], chars);
220  }
221 
222 }
223 
224