Root/src/inputdialog.cpp

1/***************************************************************************
2 * Copyright (C) 2006 by Massimiliano Torromeo *
3 * massimiliano.torromeo@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21#include <SDL.h>
22#include <SDL_gfxPrimitives.h>
23
24#include "inputdialog.h"
25
26using namespace std;
27using namespace fastdelegate;
28
29InputDialog::InputDialog(GMenu2X *gmenu2x, InputManager &inputMgr_,
30        Touchscreen &ts_, const string &text,
31        const string &startvalue, const string &title, const string &icon)
32    : Dialog(gmenu2x)
33    , inputMgr(inputMgr_)
34    , ts(ts_)
35{
36    if (title=="") {
37        this->title = text;
38        this->text = "";
39    } else {
40        this->title = title;
41        this->text = text;
42    }
43    this->icon = "";
44    if (icon!="" && gmenu2x->sc[icon] != NULL)
45        this->icon = icon;
46
47    input = startvalue;
48    selCol = 0;
49    selRow = 0;
50    keyboard.resize(7);
51
52    keyboard[0].push_back("abcdefghijklm");
53    keyboard[0].push_back("nopqrstuvwxyz");
54    keyboard[0].push_back("0123456789. ");
55
56    keyboard[1].push_back("ABCDEFGHIJKLM");
57    keyboard[1].push_back("NOPQRSTUVWXYZ");
58    keyboard[1].push_back("_\"'`.,:;!? ");
59
60
61    keyboard[2].push_back("¡¿*+-/\\&<=>|");
62    keyboard[2].push_back("()[]{}@#$%^~");
63    keyboard[2].push_back("_\"'`.,:;!? ");
64
65
66    keyboard[3].push_back("àáèéìíòóùúýäõ");
67    keyboard[3].push_back("ëïöüÿâêîôûåãñ");
68    keyboard[3].push_back("čďěľĺňôřŕšťůž");
69    keyboard[3].push_back("ąćęłńśżź ");
70
71    keyboard[4].push_back("ÀÁÈÉÌÍÒÓÙÚÝÄÕ");
72    keyboard[4].push_back("ËÏÖÜŸÂÊÎÔÛÅÃÑ");
73    keyboard[4].push_back("ČĎĚĽĹŇÔŘŔŠŤŮŽ");
74    keyboard[4].push_back("ĄĆĘŁŃŚŻŹ ");
75
76
77    keyboard[5].push_back("æçабвгдеёжзий ");
78    keyboard[5].push_back("клмнопрстуфхцч");
79    keyboard[5].push_back("шщъыьэюяøðßÐÞþ");
80
81    keyboard[6].push_back("ÆÇАБВГДЕЁЖЗИЙ ");
82    keyboard[6].push_back("КЛМНОПРСТУФХЦЧ");
83    keyboard[6].push_back("ШЩЪЫЬЭЮЯØðßÐÞþ");
84
85    setKeyboard(0);
86
87    ButtonAction actBackspace = MakeDelegate(this, &InputDialog::backspace);
88
89    btnBackspaceX = new IconButton(gmenu2x, "skin:imgs/buttons/x.png");
90    btnBackspaceX->setAction(actBackspace);
91
92    btnBackspaceL = new IconButton(gmenu2x, "skin:imgs/buttons/l.png", gmenu2x->tr["Backspace"]);
93    btnBackspaceL->setAction(actBackspace);
94
95    btnSpace = new IconButton(gmenu2x, "skin:imgs/buttons/r.png", gmenu2x->tr["Space"]);
96    btnSpace->setAction(MakeDelegate(this, &InputDialog::space));
97
98    btnConfirm = new IconButton(gmenu2x, "skin:imgs/buttons/b.png", gmenu2x->tr["Confirm"]);
99    btnConfirm->setAction(MakeDelegate(this, &InputDialog::confirm));
100
101    btnChangeKeys = new IconButton(gmenu2x, "skin:imgs/buttons/y.png", gmenu2x->tr["Change keys"]);
102    btnChangeKeys->setAction(MakeDelegate(this, &InputDialog::changeKeys));
103}
104
105void InputDialog::setKeyboard(int kb) {
106    kb = constrain(kb,0,keyboard.size()-1);
107    curKeyboard = kb;
108    this->kb = &(keyboard[kb]);
109    kbLength = this->kb->at(0).length();
110    for (int x = 0, l = kbLength; x<l; x++)
111        if (gmenu2x->font->utf8Code(this->kb->at(0)[x])) {
112            kbLength--;
113            x++;
114        }
115
116    kbLeft = 160 - kbLength*KEY_WIDTH/2;
117    kbWidth = kbLength*KEY_WIDTH+3;
118    kbHeight = (this->kb->size()+1)*KEY_HEIGHT+3;
119
120    kbRect.x = kbLeft-3;
121    kbRect.y = KB_TOP-2;
122    kbRect.w = kbWidth;
123    kbRect.h = kbHeight;
124}
125
126bool InputDialog::exec() {
127    SDL_Rect box = {0, 60, 0, gmenu2x->font->getHeight()+4};
128
129    Uint32 caretTick = 0, curTick;
130    bool caretOn = true;
131
132    uint action;
133    close = false;
134    ok = true;
135    while (!close) {
136        gmenu2x->bg->blit(gmenu2x->s,0,0);
137        writeTitle(title);
138        writeSubTitle(text);
139        drawTitleIcon(icon);
140
141        gmenu2x->drawButton(gmenu2x->s, "y", gmenu2x->tr["Change keys"],
142        gmenu2x->drawButton(gmenu2x->s, "b", gmenu2x->tr["Confirm"],
143        gmenu2x->drawButton(gmenu2x->s, "r", gmenu2x->tr["Space"],
144        gmenu2x->drawButton(btnBackspaceL,
145        gmenu2x->drawButton(btnBackspaceX)-6))));
146
147        box.w = gmenu2x->font->getTextWidth(input)+18;
148        box.x = 160-box.w/2;
149        gmenu2x->s->box(box.x, box.y, box.w, box.h,
150        gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
151        gmenu2x->s->rectangle(box.x, box.y, box.w, box.h, gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
152
153        gmenu2x->s->write(gmenu2x->font, input, box.x+5, box.y+box.h-2, ASFont::HAlignLeft, ASFont::VAlignBottom);
154
155        curTick = SDL_GetTicks();
156        if (curTick-caretTick>=600) {
157            caretOn = !caretOn;
158            caretTick = curTick;
159        }
160
161        if (caretOn) gmenu2x->s->box(box.x+box.w-12, box.y+3, 8, box.h-6, gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
162
163        if (gmenu2x->f200) ts.poll();
164        action = drawVirtualKeyboard();
165        gmenu2x->s->flip();
166
167        switch (inputMgr.waitForPressedButton()) {
168            case SETTINGS:
169                ok = false;
170                close = true;
171                break;
172            case UP:
173                selRow--;
174                break;
175            case DOWN:
176                selRow++;
177                if (selRow==(int)kb->size()) selCol = selCol<8 ? 0 : 1;
178                break;
179            case LEFT:
180                selCol--;
181                break;
182            case RIGHT:
183                selCol++;
184                break;
185            case ACCEPT:
186                confirm();
187                break;
188            case MANUAL:
189                changeKeys();
190                break;
191            case CLEAR:
192            case ALTLEFT:
193                backspace();
194                break;
195            case ALTRIGHT:
196                space();
197                break;
198            default:
199                break;
200        }
201
202
203        /*
204        inputMgr.update();
205        if ( inputMgr[ACTION_START] ) action = ID_ACTION_CLOSE;
206        if ( inputMgr[ACTION_UP ] ) action = ID_ACTION_UP;
207        if ( inputMgr[ACTION_DOWN ] ) action = ID_ACTION_DOWN;
208        if ( inputMgr[ACTION_LEFT ] ) action = ID_ACTION_LEFT;
209        if ( inputMgr[ACTION_RIGHT] ) action = ID_ACTION_RIGHT;
210        if ( inputMgr[ACTION_B] ) action = ID_ACTION_SELECT;
211        if ( inputMgr[ACTION_Y] ) action = ID_ACTION_KB_CHANGE;
212        if ( inputMgr[ACTION_X] || inputMgr[ACTION_L] ) action = ID_ACTION_BACKSPACE;
213        if ( inputMgr[ACTION_R ] ) action = ID_ACTION_SPACE;
214
215        switch (action) {
216            case ID_ACTION_CLOSE: {
217                ok = false;
218                close = true;
219            } break;
220            case ID_ACTION_UP: {
221                selRow--;
222            } break;
223            case ID_ACTION_DOWN: {
224                selRow++;
225                if (selRow==(int)kb->size()) selCol = selCol<8 ? 0 : 1;
226            } break;
227            case ID_ACTION_LEFT: {
228                selCol--;
229            } break;
230            case ID_ACTION_RIGHT: {
231                selCol++;
232            } break;
233            case ID_ACTION_BACKSPACE: backspace(); break;
234            case ID_ACTION_SPACE: space(); break;
235            case ID_ACTION_KB_CHANGE: changeKeys(); break;
236            case ID_ACTION_SELECT: confirm(); break;
237        }
238*/
239    }
240
241    return ok;
242}
243
244void InputDialog::backspace() {
245    // check for utf8 characters
246    input = input.substr(0,input.length()-( gmenu2x->font->utf8Code(input[input.length()-2]) ? 2 : 1 ));
247}
248
249void InputDialog::space() {
250    // check for utf8 characters
251    input += " ";
252}
253
254void InputDialog::confirm() {
255    if (selRow==(int)kb->size()) {
256        if (selCol==0)
257            ok = false;
258        close = true;
259    } else {
260        bool utf8;
261        int xc=0;
262        for (uint x=0; x<kb->at(selRow).length(); x++) {
263            utf8 = gmenu2x->font->utf8Code(kb->at(selRow)[x]);
264            if (xc==selCol) input += kb->at(selRow).substr(x, utf8 ? 2 : 1);
265            if (utf8) x++;
266            xc++;
267        }
268    }
269}
270
271void InputDialog::changeKeys() {
272    if (curKeyboard==6)
273        setKeyboard(0);
274    else
275        setKeyboard(curKeyboard+1);
276}
277
278int InputDialog::drawVirtualKeyboard() {
279    int action = ID_NO_ACTION;
280
281    //keyboard border
282    gmenu2x->s->rectangle(kbRect, gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
283
284    if (selCol<0) selCol = selRow==(int)kb->size() ? 1 : kbLength-1;
285    if (selCol>=(int)kbLength) selCol = 0;
286    if (selRow<0) selRow = kb->size()-1;
287    if (selRow>(int)kb->size()) selRow = 0;
288
289    //selection
290    if (selRow<(int)kb->size())
291        gmenu2x->s->box(kbLeft+selCol*KEY_WIDTH-1, KB_TOP+selRow*KEY_HEIGHT, KEY_WIDTH-1, KEY_HEIGHT-2, gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
292    else {
293        if (selCol>1) selCol = 0;
294        if (selCol<0) selCol = 1;
295        gmenu2x->s->box(kbLeft+selCol*kbLength*KEY_WIDTH/2-1,
296        KB_TOP+kb->size()*KEY_HEIGHT, kbLength*KEY_WIDTH/2-1, KEY_HEIGHT-1, gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
297    }
298
299    //keys
300    for (uint l=0; l<kb->size(); l++) {
301        string line = kb->at(l);
302        for (uint x=0, xc=0; x<line.length(); x++) {
303            string charX;
304            //utf8 characters
305            if (gmenu2x->font->utf8Code(line[x])) {
306                charX = line.substr(x,2);
307                x++;
308            } else
309                charX = line[x];
310
311            SDL_Rect re = {kbLeft+xc*KEY_WIDTH-1, KB_TOP+l*KEY_HEIGHT, KEY_WIDTH-1, KEY_HEIGHT-2};
312
313            //if ts on rect, change selection
314            if (gmenu2x->f200 && ts.pressed() && ts.inRect(re)) {
315                selCol = xc;
316                selRow = l;
317            }
318
319            gmenu2x->s->rectangle(re, gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
320            gmenu2x->s->write(gmenu2x->font, charX, kbLeft+xc*KEY_WIDTH+KEY_WIDTH/2-1, KB_TOP+l*KEY_HEIGHT+KEY_HEIGHT/2, ASFont::HAlignCenter, ASFont::VAlignMiddle);
321            xc++;
322        }
323    }
324
325    //Ok/Cancel
326    SDL_Rect re = {kbLeft-1, KB_TOP+kb->size()*KEY_HEIGHT, kbLength*KEY_WIDTH/2-1, KEY_HEIGHT-1};
327    gmenu2x->s->rectangle(re, gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
328    if (gmenu2x->f200 && ts.pressed() && ts.inRect(re)) {
329        selCol = 0;
330        selRow = kb->size();
331    }
332    gmenu2x->s->write(gmenu2x->font, gmenu2x->tr["Cancel"], (int)(160-kbLength*KEY_WIDTH/4), KB_TOP+kb->size()*KEY_HEIGHT+KEY_HEIGHT/2, ASFont::HAlignCenter, ASFont::VAlignMiddle);
333
334    re.x = kbLeft+kbLength*KEY_WIDTH/2-1;
335    gmenu2x->s->rectangle(re, gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
336    if (gmenu2x->f200 && ts.pressed() && ts.inRect(re)) {
337        selCol = 1;
338        selRow = kb->size();
339    }
340    gmenu2x->s->write(gmenu2x->font, gmenu2x->tr["OK"], (int)(160+kbLength*KEY_WIDTH/4), KB_TOP+kb->size()*KEY_HEIGHT+KEY_HEIGHT/2, ASFont::HAlignCenter, ASFont::VAlignMiddle);
341
342    //if ts released
343    if (gmenu2x->f200 && ts.released() && ts.inRect(kbRect)) {
344        action = ID_ACTION_SELECT;
345    }
346
347    return action;
348}
349

Archive Download this file



interactive