2010-02-04 13:33:47 +02:00
|
|
|
/***************************************************************************
|
2011-10-23 12:56:32 +03:00
|
|
|
* Copyright (C) 2006 by Massimiliano Torromeo *
|
|
|
|
* massimiliano.torromeo@gmail.com *
|
2010-02-04 13:33:47 +02:00
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
* This program is distributed in the hope that it will be useful, *
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
* GNU General Public License for more details. *
|
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU General Public License *
|
|
|
|
* along with this program; if not, write to the *
|
|
|
|
* Free Software Foundation, Inc., *
|
|
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#include "inputdialog.h"
|
|
|
|
|
2011-10-23 13:46:52 +03:00
|
|
|
#include "buttonbox.h"
|
2013-07-29 19:58:25 +03:00
|
|
|
#include "delegate.h"
|
2011-10-23 13:46:52 +03:00
|
|
|
#include "gmenu2x.h"
|
2011-10-23 18:27:29 +03:00
|
|
|
#include "iconbutton.h"
|
2013-08-03 23:30:12 +03:00
|
|
|
#include "surface.h"
|
2011-10-23 18:27:29 +03:00
|
|
|
#include "utilities.h"
|
2011-10-23 13:46:52 +03:00
|
|
|
|
|
|
|
#include <SDL_gfxPrimitives.h>
|
|
|
|
|
2010-02-04 13:33:47 +02:00
|
|
|
using namespace std;
|
|
|
|
|
2011-10-23 13:46:52 +03:00
|
|
|
#define KEY_WIDTH 20
|
|
|
|
#define KEY_HEIGHT 20
|
|
|
|
#define KB_TOP 90
|
|
|
|
|
2013-08-03 23:02:50 +03:00
|
|
|
static bool utf8Code(unsigned char c)
|
|
|
|
{
|
|
|
|
return (c>=194 && c<=198) || c==208 || c==209;
|
|
|
|
}
|
|
|
|
|
2010-07-27 23:56:03 +03:00
|
|
|
InputDialog::InputDialog(GMenu2X *gmenu2x, InputManager &inputMgr_,
|
|
|
|
Touchscreen &ts_, const string &text,
|
|
|
|
const string &startvalue, const string &title, const string &icon)
|
|
|
|
: Dialog(gmenu2x)
|
|
|
|
, inputMgr(inputMgr_)
|
|
|
|
, ts(ts_)
|
2010-05-05 15:35:52 +03:00
|
|
|
{
|
2013-08-16 10:16:04 +03:00
|
|
|
if (title.empty()) {
|
2010-02-04 13:33:47 +02:00
|
|
|
this->title = text;
|
|
|
|
this->text = "";
|
|
|
|
} else {
|
|
|
|
this->title = title;
|
|
|
|
this->text = text;
|
|
|
|
}
|
|
|
|
this->icon = "";
|
2013-08-16 10:16:04 +03:00
|
|
|
if (!icon.empty() && gmenu2x->sc[icon] != NULL) {
|
2010-02-04 13:33:47 +02:00
|
|
|
this->icon = icon;
|
2011-10-23 12:56:32 +03:00
|
|
|
}
|
2010-02-04 13:33:47 +02:00
|
|
|
|
|
|
|
input = startvalue;
|
|
|
|
selCol = 0;
|
|
|
|
selRow = 0;
|
|
|
|
keyboard.resize(7);
|
|
|
|
|
|
|
|
keyboard[0].push_back("abcdefghijklm");
|
|
|
|
keyboard[0].push_back("nopqrstuvwxyz");
|
|
|
|
keyboard[0].push_back("0123456789. ");
|
|
|
|
|
|
|
|
keyboard[1].push_back("ABCDEFGHIJKLM");
|
|
|
|
keyboard[1].push_back("NOPQRSTUVWXYZ");
|
|
|
|
keyboard[1].push_back("_\"'`.,:;!? ");
|
|
|
|
|
|
|
|
|
|
|
|
keyboard[2].push_back("¡¿*+-/\\&<=>|");
|
|
|
|
keyboard[2].push_back("()[]{}@#$%^~");
|
|
|
|
keyboard[2].push_back("_\"'`.,:;!? ");
|
|
|
|
|
|
|
|
|
|
|
|
keyboard[3].push_back("àáèéìíòóùúýäõ");
|
|
|
|
keyboard[3].push_back("ëïöüÿâêîôûåãñ");
|
|
|
|
keyboard[3].push_back("čďěľĺňôřŕšťůž");
|
|
|
|
keyboard[3].push_back("ąćęłńśżź ");
|
|
|
|
|
|
|
|
keyboard[4].push_back("ÀÁÈÉÌÍÒÓÙÚÝÄÕ");
|
|
|
|
keyboard[4].push_back("ËÏÖÜŸÂÊÎÔÛÅÃÑ");
|
|
|
|
keyboard[4].push_back("ČĎĚĽĹŇÔŘŔŠŤŮŽ");
|
|
|
|
keyboard[4].push_back("ĄĆĘŁŃŚŻŹ ");
|
|
|
|
|
|
|
|
|
|
|
|
keyboard[5].push_back("æçабвгдеёжзий ");
|
|
|
|
keyboard[5].push_back("клмнопрстуфхцч");
|
|
|
|
keyboard[5].push_back("шщъыьэюяøðßÐÞþ");
|
|
|
|
|
|
|
|
keyboard[6].push_back("ÆÇАБВГДЕЁЖЗИЙ ");
|
|
|
|
keyboard[6].push_back("КЛМНОПРСТУФХЦЧ");
|
|
|
|
keyboard[6].push_back("ШЩЪЫЬЭЮЯØðßÐÞþ");
|
|
|
|
|
|
|
|
setKeyboard(0);
|
|
|
|
|
2011-09-18 03:05:15 +03:00
|
|
|
buttonbox = new ButtonBox(gmenu2x);
|
2011-12-23 15:03:05 +02:00
|
|
|
IconButton *btnBackspace = new IconButton(gmenu2x, ts,
|
2011-10-23 12:56:32 +03:00
|
|
|
"skin:imgs/buttons/l.png", gmenu2x->tr["Backspace"]);
|
2013-07-29 19:58:25 +03:00
|
|
|
btnBackspace->setAction(BIND(&InputDialog::backspace));
|
2011-09-18 03:05:15 +03:00
|
|
|
buttonbox->add(btnBackspace);
|
2010-02-04 13:33:47 +02:00
|
|
|
|
2011-12-23 15:03:05 +02:00
|
|
|
IconButton *btnSpace = new IconButton(gmenu2x, ts,
|
2011-10-23 12:56:32 +03:00
|
|
|
"skin:imgs/buttons/r.png", gmenu2x->tr["Space"]);
|
2013-07-29 19:58:25 +03:00
|
|
|
btnSpace->setAction(BIND(&InputDialog::space));
|
2011-09-18 03:05:15 +03:00
|
|
|
buttonbox->add(btnSpace);
|
2010-02-04 13:33:47 +02:00
|
|
|
|
2011-12-23 15:03:05 +02:00
|
|
|
IconButton *btnConfirm = new IconButton(gmenu2x, ts,
|
2011-10-23 12:56:32 +03:00
|
|
|
"skin:imgs/buttons/accept.png", gmenu2x->tr["Confirm"]);
|
2013-07-29 19:58:25 +03:00
|
|
|
btnConfirm->setAction(BIND(&InputDialog::confirm));
|
2011-09-18 03:05:15 +03:00
|
|
|
buttonbox->add(btnConfirm);
|
2010-02-04 13:33:47 +02:00
|
|
|
|
2011-12-23 15:03:05 +02:00
|
|
|
IconButton *btnChangeKeys = new IconButton(gmenu2x, ts,
|
2011-10-23 12:56:32 +03:00
|
|
|
"skin:imgs/buttons/cancel.png", gmenu2x->tr["Change keys"]);
|
2013-07-29 19:58:25 +03:00
|
|
|
btnChangeKeys->setAction(BIND(&InputDialog::changeKeys));
|
2011-09-18 03:05:15 +03:00
|
|
|
buttonbox->add(btnChangeKeys);
|
2010-02-04 13:33:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void InputDialog::setKeyboard(int kb) {
|
2011-10-23 12:56:32 +03:00
|
|
|
kb = constrain(kb, 0, keyboard.size() - 1);
|
2010-02-04 13:33:47 +02:00
|
|
|
curKeyboard = kb;
|
|
|
|
this->kb = &(keyboard[kb]);
|
|
|
|
kbLength = this->kb->at(0).length();
|
2011-10-23 12:56:32 +03:00
|
|
|
for (int x = 0, l = kbLength; x < l; x++) {
|
2013-08-03 23:02:50 +03:00
|
|
|
if (utf8Code(this->kb->at(0)[x])) {
|
2010-02-04 13:33:47 +02:00
|
|
|
kbLength--;
|
|
|
|
x++;
|
|
|
|
}
|
2011-10-23 12:56:32 +03:00
|
|
|
}
|
2010-02-04 13:33:47 +02:00
|
|
|
|
2011-10-23 12:56:32 +03:00
|
|
|
kbLeft = 160 - kbLength * KEY_WIDTH / 2;
|
|
|
|
kbWidth = kbLength * KEY_WIDTH + 3;
|
|
|
|
kbHeight = (this->kb->size() + 1) * KEY_HEIGHT + 3;
|
2010-02-04 13:33:47 +02:00
|
|
|
|
2011-10-23 12:56:32 +03:00
|
|
|
kbRect.x = kbLeft - 3;
|
|
|
|
kbRect.y = KB_TOP - 2;
|
2010-02-04 13:33:47 +02:00
|
|
|
kbRect.w = kbWidth;
|
|
|
|
kbRect.h = kbHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool InputDialog::exec() {
|
2012-04-11 00:01:16 +03:00
|
|
|
SDL_Rect box = {
|
|
|
|
0, 60, 0, static_cast<Uint16>(gmenu2x->font->getHeight() + 4)
|
|
|
|
};
|
2010-02-04 13:33:47 +02:00
|
|
|
|
|
|
|
Uint32 caretTick = 0, curTick;
|
|
|
|
bool caretOn = true;
|
|
|
|
|
|
|
|
close = false;
|
|
|
|
ok = true;
|
|
|
|
while (!close) {
|
|
|
|
gmenu2x->bg->blit(gmenu2x->s,0,0);
|
2010-05-05 15:35:52 +03:00
|
|
|
writeTitle(title);
|
|
|
|
writeSubTitle(text);
|
|
|
|
drawTitleIcon(icon);
|
2010-02-04 13:33:47 +02:00
|
|
|
|
2011-09-18 03:05:15 +03:00
|
|
|
buttonbox->paint(5);
|
2010-02-04 13:33:47 +02:00
|
|
|
|
2011-10-23 12:56:32 +03:00
|
|
|
box.w = gmenu2x->font->getTextWidth(input) + 18;
|
|
|
|
box.x = 160 - box.w / 2;
|
2010-05-02 20:53:06 +03:00
|
|
|
gmenu2x->s->box(box.x, box.y, box.w, box.h,
|
|
|
|
gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
|
2011-10-23 12:56:32 +03:00
|
|
|
gmenu2x->s->rectangle(box.x, box.y, box.w, box.h,
|
|
|
|
gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
|
2010-02-04 13:33:47 +02:00
|
|
|
|
2011-10-23 12:56:32 +03:00
|
|
|
gmenu2x->s->write(gmenu2x->font, input, box.x + 5, box.y + box.h - 2,
|
2013-08-03 23:30:12 +03:00
|
|
|
Font::HAlignLeft, Font::VAlignBottom);
|
2010-02-04 13:33:47 +02:00
|
|
|
|
|
|
|
curTick = SDL_GetTicks();
|
2011-10-23 12:56:32 +03:00
|
|
|
if (curTick - caretTick >= 600) {
|
2010-02-04 13:33:47 +02:00
|
|
|
caretOn = !caretOn;
|
|
|
|
caretTick = curTick;
|
|
|
|
}
|
|
|
|
|
2011-10-23 12:56:32 +03:00
|
|
|
if (caretOn) {
|
|
|
|
gmenu2x->s->box(box.x + box.w - 12, box.y + 3, 8, box.h - 6,
|
|
|
|
gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
|
|
|
|
}
|
2010-02-04 13:33:47 +02:00
|
|
|
|
2011-12-23 13:30:15 +02:00
|
|
|
if (ts.available()) ts.poll();
|
2011-10-23 13:00:46 +03:00
|
|
|
drawVirtualKeyboard();
|
2010-02-04 13:33:47 +02:00
|
|
|
gmenu2x->s->flip();
|
|
|
|
|
2011-10-23 12:56:32 +03:00
|
|
|
switch (inputMgr.waitForPressedButton()) {
|
|
|
|
case InputManager::SETTINGS:
|
2013-11-30 03:27:45 +02:00
|
|
|
ok = true;
|
|
|
|
close = true;
|
|
|
|
break;
|
|
|
|
case InputManager::MENU:
|
2010-09-17 23:34:26 +03:00
|
|
|
ok = false;
|
|
|
|
close = true;
|
2011-10-23 12:56:32 +03:00
|
|
|
break;
|
|
|
|
case InputManager::UP:
|
2010-09-17 23:34:26 +03:00
|
|
|
selRow--;
|
2011-10-23 12:56:32 +03:00
|
|
|
break;
|
|
|
|
case InputManager::DOWN:
|
2010-09-17 23:34:26 +03:00
|
|
|
selRow++;
|
2011-10-23 12:56:32 +03:00
|
|
|
if (selRow == (int)kb->size()) selCol = selCol < 8 ? 0 : 1;
|
|
|
|
break;
|
|
|
|
case InputManager::LEFT:
|
2010-09-17 23:34:26 +03:00
|
|
|
selCol--;
|
2011-10-23 12:56:32 +03:00
|
|
|
break;
|
|
|
|
case InputManager::RIGHT:
|
2010-09-17 23:34:26 +03:00
|
|
|
selCol++;
|
2011-10-23 12:56:32 +03:00
|
|
|
break;
|
|
|
|
case InputManager::ACCEPT:
|
|
|
|
confirm();
|
|
|
|
break;
|
|
|
|
case InputManager::CANCEL:
|
|
|
|
changeKeys();
|
|
|
|
break;
|
|
|
|
case InputManager::ALTLEFT:
|
|
|
|
backspace();
|
|
|
|
break;
|
|
|
|
case InputManager::ALTRIGHT:
|
|
|
|
space();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2010-02-04 13:33:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
void InputDialog::backspace() {
|
2011-10-23 12:56:32 +03:00
|
|
|
// Check for UTF8 characters.
|
|
|
|
input = input.substr(0, input.length()
|
2013-08-03 23:02:50 +03:00
|
|
|
- (utf8Code(input[input.length() - 2]) ? 2 : 1));
|
2010-02-04 13:33:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void InputDialog::space() {
|
|
|
|
input += " ";
|
|
|
|
}
|
|
|
|
|
|
|
|
void InputDialog::confirm() {
|
2011-10-23 12:56:32 +03:00
|
|
|
if (selRow == (int)kb->size()) {
|
|
|
|
if (selCol == 0) {
|
2010-02-04 13:33:47 +02:00
|
|
|
ok = false;
|
2011-10-23 12:56:32 +03:00
|
|
|
}
|
2010-02-04 13:33:47 +02:00
|
|
|
close = true;
|
|
|
|
} else {
|
2011-10-23 12:56:32 +03:00
|
|
|
int xc = 0;
|
|
|
|
for (uint x = 0; x < kb->at(selRow).length(); x++) {
|
2013-08-03 23:02:50 +03:00
|
|
|
bool utf8 = utf8Code(kb->at(selRow)[x]);
|
2011-10-23 12:56:32 +03:00
|
|
|
if (xc == selCol) input += kb->at(selRow).substr(x, utf8 ? 2 : 1);
|
2010-02-04 13:33:47 +02:00
|
|
|
if (utf8) x++;
|
|
|
|
xc++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void InputDialog::changeKeys() {
|
2011-10-23 12:56:32 +03:00
|
|
|
if (curKeyboard == 6) {
|
2010-02-04 13:33:47 +02:00
|
|
|
setKeyboard(0);
|
2011-10-23 12:56:32 +03:00
|
|
|
} else {
|
|
|
|
setKeyboard(curKeyboard + 1);
|
|
|
|
}
|
2010-02-04 13:33:47 +02:00
|
|
|
}
|
|
|
|
|
2011-10-23 13:00:46 +03:00
|
|
|
void InputDialog::drawVirtualKeyboard() {
|
2010-02-04 13:33:47 +02:00
|
|
|
//keyboard border
|
2010-05-02 20:53:06 +03:00
|
|
|
gmenu2x->s->rectangle(kbRect, gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
|
2010-02-04 13:33:47 +02:00
|
|
|
|
|
|
|
if (selCol<0) selCol = selRow==(int)kb->size() ? 1 : kbLength-1;
|
|
|
|
if (selCol>=(int)kbLength) selCol = 0;
|
|
|
|
if (selRow<0) selRow = kb->size()-1;
|
|
|
|
if (selRow>(int)kb->size()) selRow = 0;
|
|
|
|
|
|
|
|
//selection
|
|
|
|
if (selRow<(int)kb->size())
|
2011-10-23 12:56:32 +03:00
|
|
|
gmenu2x->s->box(kbLeft + selCol * KEY_WIDTH - 1,
|
|
|
|
KB_TOP + selRow * KEY_HEIGHT, KEY_WIDTH - 1, KEY_HEIGHT - 2,
|
|
|
|
gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
|
2010-02-04 13:33:47 +02:00
|
|
|
else {
|
2011-10-23 12:56:32 +03:00
|
|
|
if (selCol > 1) selCol = 0;
|
|
|
|
if (selCol < 0) selCol = 1;
|
|
|
|
gmenu2x->s->box(kbLeft + selCol * kbLength * KEY_WIDTH / 2 - 1,
|
|
|
|
KB_TOP + kb->size() * KEY_HEIGHT, kbLength * KEY_WIDTH / 2 - 1,
|
|
|
|
KEY_HEIGHT - 1, gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
|
2010-02-04 13:33:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//keys
|
|
|
|
for (uint l=0; l<kb->size(); l++) {
|
|
|
|
string line = kb->at(l);
|
|
|
|
for (uint x=0, xc=0; x<line.length(); x++) {
|
|
|
|
string charX;
|
|
|
|
//utf8 characters
|
2013-08-03 23:02:50 +03:00
|
|
|
if (utf8Code(line[x])) {
|
2010-02-04 13:33:47 +02:00
|
|
|
charX = line.substr(x,2);
|
|
|
|
x++;
|
|
|
|
} else
|
|
|
|
charX = line[x];
|
|
|
|
|
2011-10-23 12:56:32 +03:00
|
|
|
SDL_Rect re = {
|
2012-04-11 00:01:16 +03:00
|
|
|
static_cast<Sint16>(kbLeft + xc * KEY_WIDTH - 1),
|
|
|
|
static_cast<Sint16>(KB_TOP + l * KEY_HEIGHT),
|
|
|
|
KEY_WIDTH - 1,
|
|
|
|
KEY_HEIGHT - 2
|
2011-10-23 12:56:32 +03:00
|
|
|
};
|
2010-02-04 13:33:47 +02:00
|
|
|
|
|
|
|
//if ts on rect, change selection
|
2011-12-23 13:30:15 +02:00
|
|
|
if (ts.available() && ts.pressed() && ts.inRect(re)) {
|
2010-02-04 13:33:47 +02:00
|
|
|
selCol = xc;
|
|
|
|
selRow = l;
|
|
|
|
}
|
|
|
|
|
2011-10-23 12:56:32 +03:00
|
|
|
gmenu2x->s->rectangle(re,
|
|
|
|
gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
|
|
|
|
gmenu2x->s->write(gmenu2x->font, charX,
|
|
|
|
kbLeft + xc * KEY_WIDTH + KEY_WIDTH / 2 - 1,
|
|
|
|
KB_TOP + l * KEY_HEIGHT + KEY_HEIGHT / 2,
|
2013-08-03 23:30:12 +03:00
|
|
|
Font::HAlignCenter, Font::VAlignMiddle);
|
2010-02-04 13:33:47 +02:00
|
|
|
xc++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//Ok/Cancel
|
2012-04-11 00:01:16 +03:00
|
|
|
SDL_Rect re = {
|
|
|
|
static_cast<Sint16>(kbLeft - 1),
|
|
|
|
static_cast<Sint16>(KB_TOP + kb->size() * KEY_HEIGHT),
|
|
|
|
static_cast<Uint16>(kbLength * KEY_WIDTH / 2 - 1),
|
|
|
|
KEY_HEIGHT - 1
|
|
|
|
};
|
2010-05-02 20:53:06 +03:00
|
|
|
gmenu2x->s->rectangle(re, gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
|
2011-12-23 13:30:15 +02:00
|
|
|
if (ts.available() && ts.pressed() && ts.inRect(re)) {
|
2010-02-04 13:33:47 +02:00
|
|
|
selCol = 0;
|
|
|
|
selRow = kb->size();
|
|
|
|
}
|
2011-10-23 12:56:32 +03:00
|
|
|
gmenu2x->s->write(gmenu2x->font, gmenu2x->tr["Cancel"],
|
|
|
|
(int)(160 - kbLength * KEY_WIDTH / 4),
|
|
|
|
KB_TOP + kb->size() * KEY_HEIGHT + KEY_HEIGHT / 2,
|
2013-08-03 23:30:12 +03:00
|
|
|
Font::HAlignCenter, Font::VAlignMiddle);
|
2010-02-04 13:33:47 +02:00
|
|
|
|
2011-10-23 12:56:32 +03:00
|
|
|
re.x = kbLeft + kbLength * KEY_WIDTH / 2 - 1;
|
2010-05-02 20:53:06 +03:00
|
|
|
gmenu2x->s->rectangle(re, gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
|
2011-12-23 13:30:15 +02:00
|
|
|
if (ts.available() && ts.pressed() && ts.inRect(re)) {
|
2010-02-04 13:33:47 +02:00
|
|
|
selCol = 1;
|
|
|
|
selRow = kb->size();
|
|
|
|
}
|
2011-10-23 12:56:32 +03:00
|
|
|
gmenu2x->s->write(gmenu2x->font, gmenu2x->tr["OK"],
|
|
|
|
(int)(160 + kbLength * KEY_WIDTH / 4),
|
|
|
|
KB_TOP + kb->size() * KEY_HEIGHT + KEY_HEIGHT / 2,
|
2013-08-03 23:30:12 +03:00
|
|
|
Font::HAlignCenter, Font::VAlignMiddle);
|
2010-02-04 13:33:47 +02:00
|
|
|
}
|