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 |
|
---|
26 | EditTextWidget::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 |
|
---|
42 | void 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 |
|
---|
54 | void 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 |
|
---|
59 | bool 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 |
|
---|
129 | void 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 |
|
---|
143 | int 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 |
|
---|
154 | void 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 |
|
---|
176 | bool 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 | }
|
---|