diff options
author | Mathias Gumz <akira at fluxbox dot org> | 2010-09-08 18:17:21 (GMT) |
---|---|---|
committer | Mathias Gumz <akira at fluxbox dot org> | 2010-09-08 18:17:21 (GMT) |
commit | 690d926ac444243611cd875fb84fabb4e6db2cf2 (patch) | |
tree | c8ef84056b295071f9a9207ffea5393c6cf4ad4d /src/FbTk/TextBox.cc | |
parent | 1e8fe2bc14856fa16508686a28a85e72cb0e422c (diff) | |
download | fluxbox-690d926ac444243611cd875fb84fabb4e6db2cf2.zip fluxbox-690d926ac444243611cd875fb84fabb4e6db2cf2.tar.bz2 |
introduced FbTk::BidiString
a 'BidiString' holds both the logical content and the visual reordered
version of the content of a string. this helps to reduce the number of
calls to reorder the string before drawing it (as introduced in the patch
from Ken Bloom) and to be more consistent in menus and textboxes (drawing
cursors and underlining text).
Diffstat (limited to 'src/FbTk/TextBox.cc')
-rw-r--r-- | src/FbTk/TextBox.cc | 63 |
1 files changed, 37 insertions, 26 deletions
diff --git a/src/FbTk/TextBox.cc b/src/FbTk/TextBox.cc index 87e18e8..74771a6 100644 --- a/src/FbTk/TextBox.cc +++ b/src/FbTk/TextBox.cc | |||
@@ -75,7 +75,7 @@ TextBox::~TextBox() { | |||
75 | 75 | ||
76 | } | 76 | } |
77 | 77 | ||
78 | void TextBox::setText(const std::string &text) { | 78 | void TextBox::setText(const FbTk::BiDiString &text) { |
79 | m_text = text; | 79 | m_text = text; |
80 | m_start_pos = 0; | 80 | m_start_pos = 0; |
81 | cursorEnd(); | 81 | cursorEnd(); |
@@ -129,7 +129,9 @@ void TextBox::cursorBackward() { | |||
129 | 129 | ||
130 | void TextBox::backspace() { | 130 | void TextBox::backspace() { |
131 | if (m_start_pos || cursorPosition()) { | 131 | if (m_start_pos || cursorPosition()) { |
132 | m_text.erase(m_start_pos + cursorPosition() - 1, 1); | 132 | FbString t = text(); |
133 | t.erase(m_start_pos + cursorPosition() - 1, 1); | ||
134 | m_text.setLogical(t); | ||
133 | if (cursorPosition()) | 135 | if (cursorPosition()) |
134 | setCursorPosition(cursorPosition() - 1); | 136 | setCursorPosition(cursorPosition() - 1); |
135 | else | 137 | else |
@@ -140,23 +142,28 @@ void TextBox::backspace() { | |||
140 | 142 | ||
141 | void TextBox::deleteForward() { | 143 | void TextBox::deleteForward() { |
142 | if (m_start_pos + m_cursor_pos < m_end_pos) { | 144 | if (m_start_pos + m_cursor_pos < m_end_pos) { |
143 | m_text.erase(m_start_pos + m_cursor_pos, 1); | 145 | FbString t = text(); |
146 | t.erase(m_start_pos + m_cursor_pos, 1); | ||
147 | m_text.setLogical(t); | ||
144 | adjustEndPos(); | 148 | adjustEndPos(); |
145 | } | 149 | } |
146 | } | 150 | } |
147 | 151 | ||
148 | void TextBox::insertText(const std::string &val) { | 152 | void TextBox::insertText(const std::string &val) { |
149 | m_text.insert(m_start_pos + cursorPosition(), val); | 153 | FbString t = text(); |
154 | t.insert(m_start_pos + cursorPosition(), val); | ||
155 | m_text.setLogical(t); | ||
150 | m_cursor_pos += val.size(); | 156 | m_cursor_pos += val.size(); |
151 | m_end_pos += val.size(); | 157 | m_end_pos += val.size(); |
152 | 158 | ||
153 | adjustPos(); | 159 | adjustPos(); |
154 | } | 160 | } |
155 | 161 | ||
156 | void TextBox::killToEnd() { | 162 | void TextBox::killToEnd() { |
157 | if (cursorPosition() >= 0 && cursorPosition() < static_cast<signed>(text().size())) { | 163 | if (cursorPosition() >= 0 && cursorPosition() < static_cast<signed>(text().size())) { |
158 | m_text.erase(cursorPosition()); | 164 | FbString t = text(); |
159 | setText(m_text); | 165 | t.erase(cursorPosition()); |
166 | setText(t); | ||
160 | } | 167 | } |
161 | } | 168 | } |
162 | 169 | ||
@@ -168,13 +175,13 @@ void TextBox::clear() { | |||
168 | setGC(DefaultGC(FbTk::App::instance()->display(), screenNumber())); | 175 | setGC(DefaultGC(FbTk::App::instance()->display(), screenNumber())); |
169 | 176 | ||
170 | font().drawText(*this, screenNumber(), | 177 | font().drawText(*this, screenNumber(), |
171 | gc(), | 178 | gc(), |
172 | text().c_str() + m_start_pos, | 179 | m_text.visual().c_str() + m_start_pos, |
173 | m_end_pos - m_start_pos, | 180 | m_end_pos - m_start_pos, |
174 | 0, center_pos); // pos | 181 | 0, center_pos); // pos |
175 | 182 | ||
176 | // draw cursor position | 183 | // draw cursor position |
177 | int cursor_pos = font().textWidth(text().c_str() + m_start_pos, m_cursor_pos) + 1; | 184 | int cursor_pos = font().textWidth(m_text.visual().c_str() + m_start_pos, m_cursor_pos) + 1; |
178 | drawLine(gc(), cursor_pos, center_pos, cursor_pos, center_pos - font().height()); | 185 | drawLine(gc(), cursor_pos, center_pos, cursor_pos, center_pos - font().height()); |
179 | } | 186 | } |
180 | 187 | ||
@@ -202,9 +209,7 @@ void TextBox::buttonPressEvent(XButtonEvent &event) { | |||
202 | int tmp = 0; | 209 | int tmp = 0; |
203 | for(i = m_start_pos; i <= m_end_pos; i++) { | 210 | for(i = m_start_pos; i <= m_end_pos; i++) { |
204 | tmp = abs(static_cast<int> | 211 | tmp = abs(static_cast<int> |
205 | (event.x - font(). | 212 | (event.x - font().textWidth(m_text.visual().c_str() + m_start_pos, i - m_start_pos))); |
206 | textWidth(m_text.c_str() + m_start_pos, | ||
207 | i - m_start_pos))); | ||
208 | 213 | ||
209 | if (tmp < delta) { | 214 | if (tmp < delta) { |
210 | delta = tmp; | 215 | delta = tmp; |
@@ -244,7 +249,7 @@ void TextBox::keyPressEvent(XKeyEvent &event) { | |||
244 | } | 249 | } |
245 | break; | 250 | break; |
246 | case XK_Right: | 251 | case XK_Right: |
247 | if (m_text.size() && m_cursor_pos < m_text.size()){ | 252 | if (!m_text.logical().empty() && m_cursor_pos < m_text.logical().size()){ |
248 | unsigned int pos = findEmptySpaceRight(); | 253 | unsigned int pos = findEmptySpaceRight(); |
249 | if (pos > m_start_pos) | 254 | if (pos > m_start_pos) |
250 | pos -= m_start_pos; | 255 | pos -= m_start_pos; |
@@ -264,7 +269,9 @@ void TextBox::keyPressEvent(XKeyEvent &event) { | |||
264 | 269 | ||
265 | case XK_BackSpace: { | 270 | case XK_BackSpace: { |
266 | unsigned int pos = findEmptySpaceLeft(); | 271 | unsigned int pos = findEmptySpaceLeft(); |
267 | m_text.erase(pos, m_cursor_pos - pos + m_start_pos); | 272 | FbString t = text(); |
273 | t.erase(pos, m_cursor_pos - pos + m_start_pos); | ||
274 | m_text.setLogical(t); | ||
268 | 275 | ||
269 | if (pos < m_start_pos){ | 276 | if (pos < m_start_pos){ |
270 | m_start_pos = pos; | 277 | m_start_pos = pos; |
@@ -278,10 +285,12 @@ void TextBox::keyPressEvent(XKeyEvent &event) { | |||
278 | } | 285 | } |
279 | break; | 286 | break; |
280 | case XK_Delete: { | 287 | case XK_Delete: { |
281 | if (!m_text.size() || m_cursor_pos >= m_text.size()) | 288 | if (text().empty() || m_cursor_pos >= text().size()) |
282 | break; | 289 | break; |
283 | unsigned int pos = findEmptySpaceRight(); | 290 | unsigned int pos = findEmptySpaceRight(); |
284 | m_text.erase(m_cursor_pos + m_start_pos, pos - (m_cursor_pos + m_start_pos)); | 291 | FbString t = text(); |
292 | t.erase(m_cursor_pos + m_start_pos, pos - (m_cursor_pos + m_start_pos)); | ||
293 | m_text.setLogical(t); | ||
285 | adjustPos(); | 294 | adjustPos(); |
286 | } | 295 | } |
287 | break; | 296 | break; |
@@ -368,15 +377,17 @@ void TextBox::adjustEndPos() { | |||
368 | } | 377 | } |
369 | 378 | ||
370 | void TextBox::adjustStartPos() { | 379 | void TextBox::adjustStartPos() { |
371 | 380 | ||
372 | int text_width = font().textWidth(text(), m_end_pos); | 381 | const char* visual = m_text.visual().c_str(); |
382 | |||
383 | int text_width = font().textWidth(visual, m_end_pos); | ||
373 | if (text_width < static_cast<signed>(width())) | 384 | if (text_width < static_cast<signed>(width())) |
374 | return; | 385 | return; |
375 | 386 | ||
376 | int start_pos = 0; | 387 | int start_pos = 0; |
377 | while (text_width > static_cast<signed>(width())) { | 388 | while (text_width > static_cast<signed>(width())) { |
378 | start_pos++; | 389 | start_pos++; |
379 | text_width = font().textWidth(text().c_str() + start_pos, m_end_pos - start_pos); | 390 | text_width = font().textWidth(visual + start_pos, m_end_pos - start_pos); |
380 | } | 391 | } |
381 | 392 | ||
382 | // adjust cursorPosition() according relative to change to m_start_pos | 393 | // adjust cursorPosition() according relative to change to m_start_pos |
@@ -387,12 +398,12 @@ void TextBox::adjustStartPos() { | |||
387 | unsigned int TextBox::findEmptySpaceLeft(){ | 398 | unsigned int TextBox::findEmptySpaceLeft(){ |
388 | 399 | ||
389 | // found the first left space symbol | 400 | // found the first left space symbol |
390 | int pos = m_text.rfind(' ', (m_start_pos + m_cursor_pos) > 0 ? | 401 | int pos = text().rfind(' ', (m_start_pos + m_cursor_pos) > 0 ? |
391 | m_start_pos + m_cursor_pos - 1 : 0); | 402 | m_start_pos + m_cursor_pos - 1 : 0); |
392 | 403 | ||
393 | // do we have one more space symbol near? | 404 | // do we have one more space symbol near? |
394 | int next_pos = -1; | 405 | int next_pos = -1; |
395 | while (pos > 0 && (next_pos = m_text.rfind(' ', pos - 1)) > -1){ | 406 | while (pos > 0 && (next_pos = text().rfind(' ', pos - 1)) > -1){ |
396 | if (next_pos + 1 < pos) | 407 | if (next_pos + 1 < pos) |
397 | break; | 408 | break; |
398 | pos = next_pos; | 409 | pos = next_pos; |
@@ -406,18 +417,18 @@ unsigned int TextBox::findEmptySpaceLeft(){ | |||
406 | unsigned int TextBox::findEmptySpaceRight(){ | 417 | unsigned int TextBox::findEmptySpaceRight(){ |
407 | 418 | ||
408 | // found the first right space symbol | 419 | // found the first right space symbol |
409 | int pos = m_text.find(' ', m_start_pos + m_cursor_pos); | 420 | int pos = text().find(' ', m_start_pos + m_cursor_pos); |
410 | 421 | ||
411 | // do we have one more space symbol near? | 422 | // do we have one more space symbol near? |
412 | int next_pos = -1; | 423 | int next_pos = -1; |
413 | while (pos > -1 && pos < static_cast<signed>(m_text.size()) && (next_pos = m_text.find(' ', pos + 1)) > -1 ){ | 424 | while (pos > -1 && pos < static_cast<signed>(text().size()) && (next_pos = text().find(' ', pos + 1)) > -1 ){ |
414 | 425 | ||
415 | if (next_pos - 1 > pos) | 426 | if (next_pos - 1 > pos) |
416 | break; | 427 | break; |
417 | pos = next_pos; | 428 | pos = next_pos; |
418 | } | 429 | } |
419 | if (pos < 0) | 430 | if (pos < 0) |
420 | pos = m_text.size() - 1; | 431 | pos = text().size() - 1; |
421 | 432 | ||
422 | return pos + 1; // (+1) - sets cursor at the right. | 433 | return pos + 1; // (+1) - sets cursor at the right. |
423 | 434 | ||