mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-30 17:01:15 +02:00
Replacing messagebox, hintbox_ext and some derivated parts with basic class hintbox and derivated class CMsgBox. This should unify window handling and avoids maintain of multiple classes with quasi same purpose and adds more functionality. TODO: fix and optimize details
920 lines
23 KiB
C++
920 lines
23 KiB
C++
/*
|
|
Neutrino-GUI - DBoxII-Project
|
|
|
|
Copyright (C) 2001 Steffen Hehn 'McClean'
|
|
Homepage: http://dbox.cyberphoria.org/
|
|
|
|
Copyright (C) 2009-2012 Stefan Seyfried
|
|
|
|
License: GPL
|
|
|
|
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <gui/widget/stringinput.h>
|
|
|
|
#include <driver/fontrenderer.h>
|
|
#include <driver/rcinput.h>
|
|
#include <driver/screen_max.h>
|
|
#include <driver/display.h>
|
|
|
|
#include <gui/color.h>
|
|
|
|
#include <gui/widget/buttons.h>
|
|
#include <gui/widget/icons.h>
|
|
#include <gui/widget/msgbox.h>
|
|
|
|
#include <system/helpers.h>
|
|
|
|
#include <global.h>
|
|
#include <neutrino.h>
|
|
|
|
CStringInput::CStringInput(const neutrino_locale_t Name, std::string* Value, int Size, const neutrino_locale_t Hint_1, const neutrino_locale_t Hint_2, const char * const Valid_Chars, CChangeObserver* Observ, const char * const Icon)
|
|
{
|
|
name = Name;
|
|
head = g_Locale->getText(Name);
|
|
valueString = Value;
|
|
lower_bound = -1;
|
|
upper_bound = -1;
|
|
size = Size;
|
|
|
|
hint_1 = Hint_1;
|
|
hint_2 = Hint_2;
|
|
validchars = Valid_Chars;
|
|
iconfile = Icon ? Icon : "";
|
|
|
|
observ = Observ;
|
|
init();
|
|
}
|
|
|
|
CStringInput::CStringInput(const std::string &Name, std::string *Value, int Size, const neutrino_locale_t Hint_1, const neutrino_locale_t Hint_2, const char * const Valid_Chars, CChangeObserver* Observ, const char * const Icon)
|
|
{
|
|
name = NONEXISTANT_LOCALE;
|
|
head = Name;
|
|
valueString = Value;
|
|
lower_bound = -1;
|
|
upper_bound = -1;
|
|
size = Size;
|
|
|
|
hint_1 = Hint_1;
|
|
hint_2 = Hint_2;
|
|
validchars = Valid_Chars;
|
|
iconfile = Icon ? Icon : "";
|
|
|
|
observ = Observ;
|
|
init();
|
|
}
|
|
|
|
CStringInput::~CStringInput()
|
|
{
|
|
g_RCInput->killTimer (smstimer);
|
|
}
|
|
|
|
void CStringInput::setMinMax(const int min_value, const int max_value)
|
|
{
|
|
lower_bound = min_value - 1;
|
|
upper_bound = max_value + 1;
|
|
}
|
|
|
|
#define CStringInputSMSButtonsCount 2
|
|
const struct button_label CStringInputSMSButtons[CStringInputSMSButtonsCount] =
|
|
{
|
|
{ NEUTRINO_ICON_BUTTON_RED , LOCALE_STRINGINPUT_CAPS },
|
|
{ NEUTRINO_ICON_BUTTON_YELLOW, LOCALE_STRINGINPUT_CLEAR }
|
|
};
|
|
|
|
void CStringInput::init()
|
|
{
|
|
frameBuffer = CFrameBuffer::getInstance();
|
|
|
|
#ifdef DEBUG_STRINGINPUT
|
|
printf("HEAD: %s (len: %d)\n", head, strlen(head));
|
|
#endif
|
|
hheight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getHeight();
|
|
iheight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_INFO]->getHeight();
|
|
fheight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_FOOT]->getHeight() + 6; // init min buttonbar height
|
|
input_h = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getHeight() + 2; // font height + border
|
|
input_w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth("M") + 2; // hack font width + border
|
|
offset = 20;
|
|
|
|
width = std::max(size*input_w + 2*offset, (int) frameBuffer->getScreenWidth() / 100 * 45);
|
|
|
|
int tmp_w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getRenderWidth(head);
|
|
|
|
if (!(iconfile.empty()))
|
|
{
|
|
int icol_w, icol_h;
|
|
frameBuffer->getIconSize(iconfile.c_str(), &icol_w, &icol_h);
|
|
hheight = std::max(hheight, icol_h + (offset/4));
|
|
tmp_w += icol_w + (offset/2);
|
|
}
|
|
width = std::max(width, tmp_w + offset);
|
|
|
|
bheight = input_h + 2*offset;
|
|
if ((hint_1 != NONEXISTANT_LOCALE) || (hint_2 != NONEXISTANT_LOCALE))
|
|
{
|
|
if (hint_1 != NONEXISTANT_LOCALE)
|
|
{
|
|
tmp_w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_INFO]->getRenderWidth(g_Locale->getText(hint_1));
|
|
width = std::max(width, tmp_w + 2*offset);
|
|
bheight += iheight;
|
|
}
|
|
if (hint_2 != NONEXISTANT_LOCALE)
|
|
{
|
|
tmp_w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_INFO]->getRenderWidth(g_Locale->getText(hint_2));
|
|
width = std::max(width, tmp_w + 2*offset);
|
|
bheight += iheight;
|
|
}
|
|
bheight += offset;
|
|
}
|
|
|
|
height = hheight+ bheight; // space for the possible numpad and the buttonbar will be added in initSMS()
|
|
|
|
x = getScreenStartX(width);
|
|
y = getScreenStartY(height);
|
|
selected = 0;
|
|
smstimer = 0;
|
|
}
|
|
|
|
void CStringInput::NormalKeyPressed(const neutrino_msg_t key)
|
|
{
|
|
if (CRCInput::isNumeric(key))
|
|
{
|
|
std::string tmp_value = *valueString;
|
|
if (selected >= (int)valueString->length())
|
|
valueString->append(selected - valueString->length() + 1, ' ');
|
|
valueString->at(selected) = validchars[CRCInput::getNumericValue(key)];
|
|
int current_value = atoi(*valueString);
|
|
int tmp = current_value;
|
|
if (lower_bound != -1 || upper_bound != -1)
|
|
{
|
|
if (current_value <= lower_bound)
|
|
current_value = lower_bound + 1;
|
|
else if (current_value >= upper_bound)
|
|
current_value = upper_bound - 1;
|
|
if (tmp != current_value)
|
|
*valueString = to_string(current_value).substr(0, size);
|
|
}
|
|
if( (lower_bound == -1 || upper_bound == -1) || (current_value > 0 && current_value > lower_bound && current_value < upper_bound) ){
|
|
if (selected < (size - 1))
|
|
{
|
|
selected++;
|
|
paintChar(selected - 1);
|
|
}
|
|
if (tmp != current_value)
|
|
{
|
|
for (tmp = 0; tmp < size; tmp++)
|
|
paintChar(tmp);
|
|
}
|
|
else
|
|
paintChar(selected);
|
|
}else{
|
|
*valueString = tmp_value;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CStringInput::keyBackspacePressed(void)
|
|
{
|
|
if (selected > 0)
|
|
{
|
|
selected--;
|
|
for (int i = selected; i < size - 1; i++)
|
|
{
|
|
valueString->at(i) = valueString->at(i + 1);
|
|
paintChar(i);
|
|
}
|
|
valueString->at(size - 1) = ' ';
|
|
paintChar(size - 1);
|
|
}
|
|
}
|
|
|
|
|
|
void CStringInput::keyRedPressed()
|
|
{
|
|
if(lower_bound == -1 || upper_bound == -1){
|
|
if (index(validchars, ' ') != NULL)
|
|
{
|
|
valueString->at(selected) = ' ';
|
|
|
|
if (selected < (size - 1))
|
|
{
|
|
selected++;
|
|
paintChar(selected - 1);
|
|
}
|
|
|
|
paintChar(selected);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CStringInput::keyYellowPressed()
|
|
{
|
|
if(lower_bound == -1 || upper_bound == -1){
|
|
selected=0;
|
|
valueString->assign(valueString->length(), ' ');
|
|
for(int i=0 ; i < size ; i++)
|
|
paintChar(i);
|
|
}
|
|
}
|
|
|
|
void CStringInput::keyBluePressed()
|
|
{
|
|
if (((valueString->at(selected) | 32) >= 'a') && ((valueString->at(selected) | 32) <= 'z'))
|
|
{
|
|
char newValue = valueString->at(selected) ^ 32;
|
|
if (index(validchars, newValue) != NULL)
|
|
{
|
|
valueString->at(selected) = newValue;
|
|
paintChar(selected);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CStringInput::keyUpPressed()
|
|
{
|
|
int npos = 0;
|
|
std::string tmp_value = *valueString;
|
|
for(int count=0;count<(int)strlen(validchars);count++)
|
|
if(valueString->at(selected)==validchars[count])
|
|
npos = count;
|
|
npos++;
|
|
if(npos>=(int)strlen(validchars))
|
|
npos = 0;
|
|
valueString->at(selected)=validchars[npos];
|
|
|
|
int current_value = atoi(*valueString);
|
|
int tmp = current_value;
|
|
if (lower_bound != -1 || upper_bound != -1)
|
|
{
|
|
if (current_value <= lower_bound)
|
|
current_value = lower_bound + 1;
|
|
else if (current_value >= upper_bound)
|
|
current_value = upper_bound - 1;
|
|
if (tmp != current_value)
|
|
*valueString = to_string(current_value).substr(0, size);
|
|
}
|
|
if( (lower_bound == -1 || upper_bound == -1) || (current_value > 0 && current_value > lower_bound && current_value < upper_bound) ){
|
|
if (tmp != current_value)
|
|
{
|
|
for (tmp = 0; tmp < size; tmp++)
|
|
paintChar(tmp);
|
|
}
|
|
else
|
|
paintChar(selected);
|
|
}else{
|
|
*valueString = tmp_value;
|
|
}
|
|
}
|
|
|
|
void CStringInput::keyDownPressed()
|
|
{
|
|
int npos = 0;
|
|
std::string tmp_value = *valueString;
|
|
for(int count=0;count<(int)strlen(validchars);count++)
|
|
if(valueString->at(selected)==validchars[count])
|
|
npos = count;
|
|
npos--;
|
|
if(npos<0)
|
|
npos = strlen(validchars)-1;
|
|
valueString->at(selected)=validchars[npos];
|
|
|
|
int current_value = atoi(*valueString);
|
|
int tmp = current_value;
|
|
if (lower_bound != -1 || upper_bound != -1)
|
|
{
|
|
if (current_value <= lower_bound)
|
|
current_value = lower_bound + 1;
|
|
else if (current_value >= upper_bound)
|
|
current_value = upper_bound - 1;
|
|
if (tmp != current_value)
|
|
*valueString = to_string(current_value).substr(0, size);
|
|
}
|
|
if( (lower_bound == -1 || upper_bound == -1) || (current_value > 0 && current_value > lower_bound && current_value < upper_bound) ){
|
|
if (tmp != current_value)
|
|
{
|
|
for (tmp = 0; tmp < size; tmp++)
|
|
paintChar(tmp);
|
|
}
|
|
else
|
|
paintChar(selected);
|
|
}else{
|
|
*valueString = tmp_value;
|
|
}
|
|
}
|
|
|
|
void CStringInput::keyLeftPressed()
|
|
{
|
|
int old = selected;
|
|
if(selected>0) {
|
|
selected--;
|
|
} else {
|
|
selected = size - 1;
|
|
}
|
|
paintChar(old);
|
|
paintChar(selected);
|
|
}
|
|
|
|
void CStringInput::keyRightPressed()
|
|
{
|
|
int old = selected;
|
|
if (selected < (size - 1)) {
|
|
selected++;
|
|
} else
|
|
selected = 0;
|
|
paintChar(old);
|
|
paintChar(selected);
|
|
}
|
|
|
|
void CStringInput::keyMinusPressed()
|
|
{
|
|
if(lower_bound == -1 || upper_bound == -1){
|
|
int item = selected;
|
|
while (item < (size -1))
|
|
{
|
|
valueString->at(item) = valueString->at(item+1);
|
|
paintChar(item);
|
|
item++;
|
|
}
|
|
valueString->at(item) = ' ';
|
|
paintChar(item);
|
|
}
|
|
}
|
|
|
|
void CStringInput::keyPlusPressed()
|
|
{
|
|
if(lower_bound == -1 || upper_bound == -1){
|
|
int item = size -1;
|
|
while (item > selected)
|
|
{
|
|
valueString->at(item) = valueString->at(item-1);
|
|
paintChar(item);
|
|
item--;
|
|
}
|
|
valueString->at(item) = ' ';
|
|
paintChar(item);
|
|
}
|
|
}
|
|
|
|
std::string &CStringInput::getValue(void)
|
|
{
|
|
return *valueString;
|
|
}
|
|
|
|
int CStringInput::exec( CMenuTarget* parent, const std::string & )
|
|
{
|
|
neutrino_msg_t msg;
|
|
neutrino_msg_data_t data;
|
|
int res = menu_return::RETURN_REPAINT;
|
|
|
|
std::string oldval = *valueString;
|
|
std::string dispval = *valueString;
|
|
|
|
if (parent)
|
|
parent->hide();
|
|
|
|
if (size > (int) valueString->length())
|
|
valueString->append(size - valueString->length(), ' ');
|
|
|
|
fb_pixel_t * pixbuf = NULL;
|
|
if (!parent) {
|
|
pixbuf = new fb_pixel_t[(width + OFFSET_SHADOW) * (height + OFFSET_SHADOW)];
|
|
if (pixbuf)
|
|
frameBuffer->SaveScreen(x, y, width + OFFSET_SHADOW, height + OFFSET_SHADOW, pixbuf);
|
|
}
|
|
|
|
paint();
|
|
|
|
uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU] == 0 ? 0xFFFF : g_settings.timing[SNeutrinoSettings::TIMING_MENU]);
|
|
|
|
bool loop=true;
|
|
while (loop)
|
|
{
|
|
frameBuffer->blit();
|
|
if (*valueString != dispval)
|
|
{
|
|
CVFD::getInstance()->showMenuText(1,valueString->c_str() , selected+1);
|
|
dispval = *valueString;
|
|
}
|
|
|
|
g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd, true );
|
|
|
|
if ( msg <= CRCInput::RC_MaxRC )
|
|
timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU] == 0 ? 0xFFFF : g_settings.timing[SNeutrinoSettings::TIMING_MENU]);
|
|
|
|
if ((msg == NeutrinoMessages::EVT_TIMER) && (data == smstimer))
|
|
msg = CRCInput::RC_right;
|
|
|
|
if (msg < CRCInput::RC_nokey)
|
|
g_RCInput->killTimer (smstimer);
|
|
|
|
if (msg==CRCInput::RC_left)
|
|
{
|
|
keyLeftPressed();
|
|
}
|
|
else if (msg==CRCInput::RC_right)
|
|
{
|
|
keyRightPressed();
|
|
}
|
|
else if (*CRCInput::getUnicodeValue(msg))
|
|
{
|
|
NormalKeyPressed(msg);
|
|
}
|
|
else if (msg==CRCInput::RC_backspace)
|
|
{
|
|
keyBackspacePressed();
|
|
}
|
|
else if (msg==CRCInput::RC_red)
|
|
{
|
|
keyRedPressed();
|
|
}
|
|
else if (msg==CRCInput::RC_yellow)
|
|
{
|
|
keyYellowPressed();
|
|
}
|
|
else if ( (msg==CRCInput::RC_green) && (index(validchars, '.') != NULL))
|
|
{
|
|
valueString->at(selected) = '.';
|
|
|
|
if (selected < (size - 1))
|
|
{
|
|
selected++;
|
|
paintChar(selected - 1);
|
|
}
|
|
|
|
paintChar(selected);
|
|
}
|
|
else if (msg== CRCInput::RC_blue)
|
|
{
|
|
keyBluePressed();
|
|
}
|
|
else if (msg==CRCInput::RC_up)
|
|
{
|
|
keyUpPressed();
|
|
}
|
|
else if (msg==CRCInput::RC_down)
|
|
{
|
|
keyDownPressed();
|
|
} else if (msg==(neutrino_msg_t)g_settings.key_volumeup)
|
|
{
|
|
keyPlusPressed();
|
|
} else if (msg==(neutrino_msg_t)g_settings.key_volumedown)
|
|
{
|
|
keyMinusPressed();
|
|
}
|
|
else if (msg==CRCInput::RC_ok)
|
|
{
|
|
loop=false;
|
|
}
|
|
else if ( (msg==CRCInput::RC_home) || (msg==CRCInput::RC_timeout) )
|
|
{
|
|
if ((*valueString != oldval) &&
|
|
(ShowMsg(name, LOCALE_MESSAGEBOX_DISCARD, CMsgBox::mbrYes, CMsgBox::mbYes | CMsgBox::mbCancel) == CMsgBox::mbrCancel)) {
|
|
timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU] == 0 ? 0xFFFF : g_settings.timing[SNeutrinoSettings::TIMING_MENU]);
|
|
continue;
|
|
}
|
|
|
|
*valueString = oldval;
|
|
loop=false;
|
|
res = menu_return::RETURN_EXIT_REPAINT;
|
|
}
|
|
else if (CNeutrinoApp::getInstance()->listModeKey(msg))
|
|
{
|
|
// do nothing
|
|
}
|
|
else
|
|
{
|
|
int r = handleOthers( msg, data );
|
|
if (r & (messages_return::cancel_all | messages_return::cancel_info))
|
|
{
|
|
res = (r & messages_return::cancel_all) ? menu_return::RETURN_EXIT_ALL : menu_return::RETURN_EXIT;
|
|
loop = false;
|
|
}
|
|
else if ( r & messages_return::unhandled )
|
|
{
|
|
if ( CNeutrinoApp::getInstance()->handleMsg( msg, data ) & messages_return::cancel_all )
|
|
{
|
|
loop = false;
|
|
res = menu_return::RETURN_EXIT_ALL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pixbuf)
|
|
{
|
|
frameBuffer->RestoreScreen(x, y, width + OFFSET_SHADOW, height + OFFSET_SHADOW, pixbuf);
|
|
delete[] pixbuf;//Mismatching allocation and deallocation: pixbuf
|
|
frameBuffer->blit();
|
|
} else
|
|
hide();
|
|
|
|
*valueString = trim (*valueString);
|
|
|
|
if ( (observ) && (msg==CRCInput::RC_ok) )
|
|
{
|
|
observ->changeNotify(name, (void *) valueString->c_str());
|
|
}
|
|
return res;
|
|
}
|
|
|
|
int CStringInput::handleOthers(const neutrino_msg_t /*msg*/, const neutrino_msg_data_t /*data*/)
|
|
{
|
|
return messages_return::unhandled;
|
|
}
|
|
|
|
void CStringInput::hide()
|
|
{
|
|
frameBuffer->paintBackgroundBoxRel(x, y, width + OFFSET_SHADOW, height + OFFSET_SHADOW);
|
|
frameBuffer->blit();
|
|
}
|
|
|
|
void CStringInput::paint(bool sms)
|
|
{
|
|
frameBuffer->paintBoxRel(x + OFFSET_SHADOW, y + OFFSET_SHADOW, width, height, COL_SHADOW_PLUS_0, RADIUS_LARGE, CORNER_ALL); //round
|
|
frameBuffer->paintBoxRel(x, y + hheight, width, bheight, COL_MENUCONTENT_PLUS_0, sms ? 0 : RADIUS_LARGE, CORNER_BOTTOM);
|
|
|
|
CComponentsHeader header(x, y, width, hheight, head, iconfile);
|
|
header.paint(CC_SAVE_SCREEN_NO);
|
|
|
|
int tmp_y = y+ hheight+ offset+ input_h+ offset;
|
|
if ((hint_1 != NONEXISTANT_LOCALE) || (hint_2 != NONEXISTANT_LOCALE))
|
|
{
|
|
if (hint_1 != NONEXISTANT_LOCALE)
|
|
{
|
|
tmp_y += iheight;
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_MENU_INFO]->RenderString(x+ offset, tmp_y, width- 2*offset, g_Locale->getText(hint_1), COL_MENUCONTENT_TEXT);
|
|
}
|
|
if (hint_2 != NONEXISTANT_LOCALE)
|
|
{
|
|
tmp_y += iheight;
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_MENU_INFO]->RenderString(x+ offset, tmp_y, width- 2*offset, g_Locale->getText(hint_2), COL_MENUCONTENT_TEXT);
|
|
}
|
|
tmp_y += offset;
|
|
}
|
|
|
|
int icol_w = 0;
|
|
int icol_h = 0;
|
|
if (sms)
|
|
{
|
|
frameBuffer->getIconSize(NEUTRINO_ICON_NUMERIC_PAD, &icol_w, &icol_h);
|
|
frameBuffer->paintIcon(NEUTRINO_ICON_NUMERIC_PAD, x + (width/2) - (icol_w/2), tmp_y);
|
|
|
|
//buttonbar
|
|
::paintButtons(x, y+ hheight+ bheight, width, CStringInputSMSButtonsCount, CStringInputSMSButtons, width, fheight);
|
|
//::paintButtons(x, y + height, width, 2, CStringInputSMSButtons, width);
|
|
}
|
|
|
|
for (int count=0;count<size;count++)
|
|
paintChar(count);
|
|
}
|
|
|
|
void CStringInput::paintChar(int pos)
|
|
{
|
|
if(pos<(int)valueString->length())
|
|
paintChar(pos, valueString->at(pos));
|
|
}
|
|
|
|
void CStringInput::paintChar(int pos, const char c)
|
|
{
|
|
int xpos = x+ offset+ pos* input_w;
|
|
int ypos = y+ hheight+ offset;
|
|
|
|
char ch[2] = {c, 0};
|
|
|
|
fb_pixel_t color;
|
|
fb_pixel_t bgcolor;
|
|
|
|
getItemColors(color, bgcolor, pos == selected);
|
|
|
|
frameBuffer->paintBoxRel(xpos, ypos, input_w, input_h, bgcolor);
|
|
frameBuffer->paintBoxFrame(xpos, ypos, input_w, input_h, 1, COL_MENUCONTENT_PLUS_2);
|
|
|
|
int ch_w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(ch);
|
|
int ch_x = xpos + std::max(input_w/2 - ch_w/2, 0);
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(ch_x, ypos+ input_h, ch_w, ch, color);
|
|
}
|
|
|
|
CStringInputSMS::CStringInputSMS(const neutrino_locale_t Name, std::string *Value, int Size, const neutrino_locale_t Hint_1, const neutrino_locale_t Hint_2, const char * const Valid_Chars, CChangeObserver* Observ, const char * const Icon)
|
|
: CStringInput(Name, Value, Size, Hint_1, Hint_2, Valid_Chars, Observ, Icon)
|
|
{
|
|
initSMS(Valid_Chars);
|
|
}
|
|
|
|
CStringInputSMS::CStringInputSMS(const std::string &Name, std::string *Value, int Size, const neutrino_locale_t Hint_1, const neutrino_locale_t Hint_2, const char * const Valid_Chars, CChangeObserver* Observ, const char * const Icon)
|
|
: CStringInput(Name, Value, Size, Hint_1, Hint_2, Valid_Chars, Observ, Icon)
|
|
{
|
|
initSMS(Valid_Chars);
|
|
}
|
|
|
|
void CStringInputSMS::initSMS(const char * const Valid_Chars)
|
|
{
|
|
last_digit = -1; // no key pressed yet
|
|
const char CharList[10][11] = { "0 -_/()<>=", // 10 characters
|
|
"1+.,:!?%\\'", //' for c't search ;)
|
|
"abc2ä",
|
|
"def3",
|
|
"ghi4",
|
|
"jkl5",
|
|
"mno6ö",
|
|
"pqrs7ß",
|
|
"tuv8ü",
|
|
"wxyz9" };
|
|
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
int j = 0;
|
|
for (int k = 0; k < (int) strlen(CharList[i]); k++)
|
|
if (strchr(Valid_Chars, CharList[i][k]) != NULL)
|
|
Chars[i][j++] = CharList[i][k];
|
|
if (j == 0)
|
|
Chars[i][j++] = ' '; // prevent empty char lists
|
|
arraySizes[i] = j;
|
|
}
|
|
|
|
int icol_w = 0, icol_h = 0;
|
|
frameBuffer->getIconSize(NEUTRINO_ICON_NUMERIC_PAD, &icol_w, &icol_h);
|
|
bheight += icol_h + offset;
|
|
|
|
icol_w = icol_h = 0;
|
|
for (int i = 0; i < CStringInputSMSButtonsCount; i++)
|
|
{
|
|
// get max iconsize in buttonbar
|
|
int w = 0, h = 0;
|
|
frameBuffer->getIconSize(CStringInputSMSButtons[i].button, &w, &h);
|
|
icol_w = std::max(icol_w, w);
|
|
icol_h = std::max(icol_h, h);
|
|
}
|
|
fheight = std::max(fheight, icol_h + offset/5);
|
|
|
|
height = hheight + bheight + fheight;
|
|
y = getScreenStartY(height);
|
|
}
|
|
|
|
void CStringInputSMS::NormalKeyPressed(const neutrino_msg_t key)
|
|
{
|
|
if (CRCInput::isNumeric(key))
|
|
{
|
|
int numericvalue = CRCInput::getNumericValue(key);
|
|
if (last_digit != numericvalue)
|
|
{
|
|
if ((last_digit != -1) && // there is a last key
|
|
(selected < (size- 1))) // we can shift the cursor one field to the right
|
|
{
|
|
selected++;
|
|
paintChar(selected - 1);
|
|
}
|
|
keyCounter = 0;
|
|
}
|
|
else
|
|
keyCounter = (keyCounter + 1) % arraySizes[numericvalue];
|
|
valueString->at(selected) = Chars[numericvalue][keyCounter];
|
|
last_digit = numericvalue;
|
|
paintChar(selected);
|
|
g_RCInput->killTimer (smstimer);
|
|
smstimer = g_RCInput->addTimer(2*1000*1000);
|
|
}
|
|
else
|
|
{
|
|
valueString->at(selected) = *CRCInput::getUnicodeValue(key);
|
|
keyRedPressed(); /* to lower, paintChar */
|
|
keyRightPressed(); /* last_digit = -1, move to next position */
|
|
}
|
|
}
|
|
|
|
void CStringInputSMS::keyBackspacePressed(void)
|
|
{
|
|
last_digit = -1;
|
|
CStringInput::keyBackspacePressed();
|
|
}
|
|
|
|
void CStringInputSMS::keyRedPressed() // switch between lower & uppercase
|
|
{
|
|
if (((valueString->at(selected) | 32) >= 'a') && ((valueString->at(selected) | 32) <= 'z'))
|
|
valueString->at(selected) ^= 32;
|
|
|
|
paintChar(selected);
|
|
}
|
|
|
|
void CStringInputSMS::keyYellowPressed() // clear all
|
|
{
|
|
last_digit = -1;
|
|
CStringInput::keyYellowPressed();
|
|
}
|
|
|
|
void CStringInputSMS::keyUpPressed()
|
|
{
|
|
last_digit = -1;
|
|
|
|
if (selected > 0)
|
|
{
|
|
int lastselected = selected;
|
|
selected = 0;
|
|
paintChar(lastselected);
|
|
paintChar(selected);
|
|
}
|
|
}
|
|
|
|
void CStringInputSMS::keyDownPressed()
|
|
{
|
|
last_digit = -1;
|
|
|
|
int lastselected = selected;
|
|
|
|
selected = size - 1;
|
|
|
|
while (valueString->at(selected) == ' ')
|
|
{
|
|
selected--;
|
|
if (selected < 0)
|
|
break;
|
|
}
|
|
|
|
if (selected < (size - 1))
|
|
selected++;
|
|
|
|
paintChar(lastselected);
|
|
paintChar(selected);
|
|
}
|
|
|
|
void CStringInputSMS::keyLeftPressed()
|
|
{
|
|
last_digit = -1;
|
|
CStringInput::keyLeftPressed();
|
|
}
|
|
|
|
void CStringInputSMS::keyRightPressed()
|
|
{
|
|
last_digit = -1;
|
|
CStringInput::keyRightPressed();
|
|
}
|
|
|
|
void CStringInputSMS::paint(bool /*unused*/)
|
|
{
|
|
CStringInput::paint(true /* sms */);
|
|
}
|
|
|
|
void CPINInput::paintChar(int pos)
|
|
{
|
|
CStringInput::paintChar(pos, (valueString->at(pos) == ' ') ? ' ' : '*');
|
|
}
|
|
|
|
int CPINInput::exec( CMenuTarget* parent, const std::string & )
|
|
{
|
|
neutrino_msg_t msg;
|
|
neutrino_msg_data_t data;
|
|
|
|
int res = menu_return::RETURN_REPAINT;
|
|
|
|
if (parent)
|
|
parent->hide();
|
|
|
|
if (size > (int) valueString->length())
|
|
valueString->append(size - valueString->length(), ' ');
|
|
|
|
paint();
|
|
|
|
bool loop = true;
|
|
|
|
while(loop)
|
|
{
|
|
frameBuffer->blit();
|
|
g_RCInput->getMsg( &msg, &data, 300 );
|
|
|
|
if (msg==CRCInput::RC_left)
|
|
{
|
|
keyLeftPressed();
|
|
}
|
|
else if (msg==CRCInput::RC_right)
|
|
{
|
|
keyRightPressed();
|
|
}
|
|
else if (CRCInput::isNumeric(msg))
|
|
{
|
|
int old_selected = selected;
|
|
NormalKeyPressed(msg);
|
|
if ( old_selected == ( size- 1 ) )
|
|
loop=false;
|
|
}
|
|
else if ( (msg==CRCInput::RC_up) ||
|
|
(msg==CRCInput::RC_down) )
|
|
{
|
|
g_RCInput->postMsg( msg, data );
|
|
res = menu_return::RETURN_EXIT;
|
|
loop=false;
|
|
}
|
|
else if ( (msg==CRCInput::RC_home) || (msg==CRCInput::RC_timeout) || (msg==CRCInput::RC_ok) )
|
|
{
|
|
loop=false;
|
|
}
|
|
else
|
|
{
|
|
int r = handleOthers(msg, data);
|
|
if (r & (messages_return::cancel_all | messages_return::cancel_info))
|
|
{
|
|
res = (r & messages_return::cancel_all) ? menu_return::RETURN_EXIT_ALL : menu_return::RETURN_EXIT;
|
|
loop = false;
|
|
}
|
|
else if ( r & messages_return::unhandled )
|
|
{
|
|
if ( CNeutrinoApp::getInstance()->handleMsg( msg, data ) & ( messages_return::cancel_all | messages_return::cancel_info ) )
|
|
{
|
|
loop = false;
|
|
res = menu_return::RETURN_EXIT_ALL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
hide();
|
|
|
|
*valueString = trim (*valueString);
|
|
|
|
if ( (observ) && (msg==CRCInput::RC_ok) )
|
|
{
|
|
observ->changeNotify(name, (void *) valueString->c_str());
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
void CEnquiryInput::paintChar(int pos)
|
|
{
|
|
if (blind)
|
|
CStringInput::paintChar(pos, (valueString->at(pos) == ' ') ? ' ' : '*');
|
|
else
|
|
CStringInput::paintChar(pos, valueString->at(pos));
|
|
}
|
|
|
|
int CPLPINInput::handleOthers(neutrino_msg_t msg, neutrino_msg_data_t data)
|
|
{
|
|
int res = messages_return::unhandled;
|
|
|
|
if ( msg == NeutrinoMessages::EVT_PROGRAMLOCKSTATUS )
|
|
{
|
|
// trotzdem handlen
|
|
CNeutrinoApp::getInstance()->handleMsg(msg, data);
|
|
|
|
if (data != (neutrino_msg_data_t) fsk)
|
|
res = messages_return::cancel_info;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
const char * CPLPINInput::getHint1(void)
|
|
{
|
|
if (fsk == 0x100)
|
|
{
|
|
hint_1 = LOCALE_PARENTALLOCK_LOCKEDCHANNEL;
|
|
return g_Locale->getText(hint_1);
|
|
}
|
|
else
|
|
{
|
|
sprintf(hint, g_Locale->getText(LOCALE_PARENTALLOCK_LOCKEDPROGRAM), fsk);
|
|
return hint;
|
|
}
|
|
}
|
|
|
|
#define borderwidth OFFSET_SHADOW // FIXME: do we need border around ??
|
|
|
|
int CPLPINInput::exec( CMenuTarget* parent, const std::string & )
|
|
{
|
|
fb_pixel_t * pixbuf = new fb_pixel_t[(width+ 2* borderwidth) * (height+ 2* borderwidth)];
|
|
|
|
if (pixbuf)
|
|
frameBuffer->SaveScreen(x- borderwidth, y- borderwidth, width+ 2* borderwidth, height+ 2* borderwidth, pixbuf);
|
|
|
|
// clear border
|
|
frameBuffer->paintBackgroundBoxRel(x- borderwidth, y- borderwidth, width+ 2* borderwidth, borderwidth);
|
|
frameBuffer->paintBackgroundBoxRel(x- borderwidth, y+ height, width+ 2* borderwidth, borderwidth);
|
|
frameBuffer->paintBackgroundBoxRel(x- borderwidth, y, borderwidth, height);
|
|
frameBuffer->paintBackgroundBoxRel(x+ width, y, borderwidth, height);
|
|
|
|
int res = CPINInput::exec ( parent, "" );
|
|
|
|
if (pixbuf)
|
|
{
|
|
frameBuffer->RestoreScreen(x - borderwidth, y- borderwidth, width+ 2* borderwidth, height+ 2* borderwidth, pixbuf);
|
|
delete[] pixbuf;//Mismatching allocation and deallocation: pixbuf
|
|
}
|
|
|
|
return ( res );
|
|
}
|