Ticket #8217: EditTextWidget.cpp

File EditTextWidget.cpp, 4.9 KB (added by wjp, 17 years ago)

EditTextWidget.cpp

Line 
1/* ScummVM - Scumm Interpreter
2 * Copyright (C) 2002-2003 The ScummVM project
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 * $Header: /cvsroot/scummvm/scummvm/gui/EditTextWidget.cpp,v 1.11 2003/05/05 10:38:16 olki Exp $
19 */
20
21#include "stdafx.h"
22#include "EditTextWidget.h"
23#include "dialog.h"
24#include "newgui.h"
25
26EditTextWidget::EditTextWidget(Dialog *boss, int x, int y, int w, int h, const String &text)
27 : StaticTextWidget(boss, x, y-1, w, h+2, text, kTextAlignLeft), _backupString(text) {
28 _flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | WIDGET_WANT_TICKLE;
29 _type = kEditTextWidget;
30
31 _caretVisible = false;
32 _caretTime = 0;
33
34 _pos = _label.size();
35
36 NewGui *gui = _boss->getGui();
37 _labelOffset = (gui->getStringWidth(_label) - (_w - 6));
38 if (_labelOffset < 0)
39 _labelOffset = 0;
40}
41
42void EditTextWidget::handleTickle() {
43 uint32 time = _boss->getGui()->get_time();
44 if (_caretTime < time) {
45 _caretTime = time + kCaretBlinkTime;
46 if (_caretVisible) {
47 drawCaret(true);
48 } else {
49 drawCaret(false);
50 }
51 }
52}
53
54void EditTextWidget::handleMouseDown(int x, int y, int button, int clickCount) {
55 // TODO - once we support "real editing" (i.e. caret can be at any spot),
56 // a mouse click should place the caret.
57}
58
59bool EditTextWidget::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
60 bool handled = true;
61 bool dirty = false;
62
63 // First remove caret
64 if (_caretVisible)
65 drawCaret(true);
66
67 switch (keycode) {
68 case '\n': // enter/return
69 case '\r':
70 _boss->releaseFocus();
71 dirty = true;
72 break;
73 case 27: // escape
74 _label = _backupString;
75 _pos = _label.size() - 1;
76 _labelOffset = (_boss->getGui()->getStringWidth(_label) - (_w-6));
77 if (_labelOffset < 0)
78 _labelOffset = 0;
79 _boss->releaseFocus();
80 dirty = true;
81 break;
82 case 8: // backspace
83 if (_pos > 0) {
84 _pos--;
85 _label.deleteChar(_pos);
86 }
87 dirty = true;
88 break;
89 case 127: // delete
90 _label.deleteChar(_pos);
91 dirty = true;
92 break;
93 case 256 + 20: // left arrow
94 if (_pos > 0) {
95 _pos--;
96 dirty = adjustOffset();
97 }
98 break;
99 case 256 + 19: // right arrow
100 if (_pos < _label.size()) {
101 _pos++;
102 dirty = adjustOffset();
103 }
104 break;
105 case 256 + 22: // home
106 _pos = 0;
107 dirty = adjustOffset();
108 break;
109 case 256 + 23: // end
110 _pos = _label.size();
111 dirty = adjustOffset();
112 break;
113 default:
114 if (isprint((char)ascii)) {
115 _label.insertChar((char)ascii, _pos++);
116 //_label += (char)ascii;
117 dirty = true;
118 } else {
119 handled = false;
120 }
121 }
122
123 if (dirty)
124 draw();
125
126 return handled;
127}
128
129void EditTextWidget::drawWidget(bool hilite) {
130 NewGui *gui = _boss->getGui();
131
132 // Draw a thin frame around us.
133 gui->hline(_x, _y, _x + _w - 1, gui->_color);
134 gui->hline(_x, _y + _h - 1, _x +_w - 1, gui->_shadowcolor);
135 gui->vline(_x, _y, _y + _h - 1, gui->_color);
136 gui->vline(_x + _w - 1, _y, _y + _h - 1, gui->_shadowcolor);
137
138 // Draw the text
139 adjustOffset();
140 gui->drawString(_label, _x + 2, _y + 3, _w - 6, gui->_textcolor, kTextAlignLeft, -_labelOffset);
141}
142
143int EditTextWidget::getCaretPos() {
144 NewGui *gui = _boss->getGui();
145 int caretpos = 0;
146 for (int i = 0; i < _pos; i++)
147 caretpos += gui->getCharWidth(_label[i]);
148
149 caretpos -= _labelOffset;
150
151 return caretpos;
152}
153
154void EditTextWidget::drawCaret(bool erase) {
155 // Only draw if item is visible
156 if (!isVisible() || !_boss->isVisible())
157 return;
158
159 NewGui *gui = _boss->getGui();
160
161 int16 color = erase ? gui->_bgcolor : gui->_textcolorhi;
162 int x = _x + _boss->getX() + 2;
163 int y = _y + _boss->getY() + 1;
164
165 int width = getCaretPos();
166 x += width;
167
168 gui->vline(x, y, y + kLineHeight, color);
169 gui->addDirtyRect(x, y, 2, kLineHeight);
170
171 _caretVisible = !erase;
172}
173
174
175
176bool EditTextWidget::adjustOffset() {
177 // check if the caret is still within the textbox; if it isn't,
178 // adjust _labelOffset
179
180 int caretpos = getCaretPos();
181
182 if (caretpos < 0) {
183 // scroll left
184 _labelOffset += caretpos;
185 return true;
186 }
187 else if (caretpos >= _w - 6)
188 {
189 // scroll right
190 _labelOffset -= (_w - 6 - caretpos);
191 return true;
192 }
193 else if (_labelOffset > 0)
194 {
195 int width = _boss->getGui()->getStringWidth(_label);
196 if (width - _labelOffset < (_w - 6)) {
197 // scroll right
198 _labelOffset = (width - (_w - 6));
199 if (_labelOffset < 0)
200 _labelOffset = 0;
201 }
202 }
203
204 return false;
205}