1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-11-26 03:06:15 +02:00

Rewrote the whole input system.

Gmenu2X will no longer eat 100% CPU ;)
This commit is contained in:
Ayla 2010-09-17 22:34:26 +02:00
parent c6c3dfe8e0
commit 563cb34a89
24 changed files with 693 additions and 388 deletions

View File

@ -68,26 +68,40 @@ bool BrowseDialog::exec()
return result;
}
BrowseDialog::Action BrowseDialog::getAction()
BrowseDialog::Action BrowseDialog::getAction(bevent_t *event)
{
BrowseDialog::Action action = BrowseDialog::ACT_NONE;
BrowseDialog::Action action;
if (gmenu2x->input[ACTION_SELECT])
action = BrowseDialog::ACT_CLOSE;
else if (gmenu2x->input[ACTION_UP])
action = BrowseDialog::ACT_UP;
else if (gmenu2x->input[ACTION_L])
action = BrowseDialog::ACT_SCROLLUP;
else if (gmenu2x->input[ACTION_DOWN])
action = BrowseDialog::ACT_DOWN;
else if (gmenu2x->input[ACTION_R])
action = BrowseDialog::ACT_SCROLLDOWN;
else if (gmenu2x->input[ACTION_X] || gmenu2x->input[ACTION_LEFT])
action = BrowseDialog::ACT_GOUP;
else if (gmenu2x->input[ACTION_B])
action = BrowseDialog::ACT_SELECT;
else if (gmenu2x->input[ACTION_START])
action = BrowseDialog::ACT_CONFIRM;
switch(event->button) {
case MENU:
action = BrowseDialog::ACT_CLOSE;
break;
case UP:
action = BrowseDialog::ACT_UP;
break;
case DOWN:
action = BrowseDialog::ACT_DOWN;
break;
case ALTLEFT:
action = BrowseDialog::ACT_SCROLLUP;
break;
case ALTRIGHT:
action = BrowseDialog::ACT_SCROLLDOWN;
break;
case LEFT:
case CLEAR:
action = BrowseDialog::ACT_GOUP;
break;
case ACCEPT:
action = BrowseDialog::ACT_SELECT;
break;
case SETTINGS:
action = BrowseDialog::ACT_CONFIRM;
break;
default:
action = BrowseDialog::ACT_NONE;
break;
}
return action;
}
@ -95,14 +109,22 @@ BrowseDialog::Action BrowseDialog::getAction()
void BrowseDialog::handleInput()
{
BrowseDialog::Action action;
bevent_t event;
gmenu2x->input.update();
do {
gmenu2x->input.waitForEvent(&event);
} while (event.state != PRESSED);
/*
while(!gmenu2x->input.update())
usleep(LOOP_DELAY);
*/
if (ts_pressed && !gmenu2x->ts.pressed()) {
action = BrowseDialog::ACT_SELECT;
ts_pressed = false;
} else {
action = getAction();
action = getAction(&event);
}
if (gmenu2x->f200 && gmenu2x->ts.pressed() && !gmenu2x->ts.inRect(touchRect)) ts_pressed = false;

View File

@ -26,6 +26,7 @@
#include "gmenu2x.h"
#include "buttonbox.h"
#include "dialog.h"
#include "inputmanager.h"
class FileLister;
@ -75,7 +76,7 @@ private:
ButtonBox buttonBox;
Action getAction();
Action getAction(bevent_t *event);
void handleInput();
void paint();

View File

@ -522,9 +522,9 @@ void GMenu2X::viewLog() {
td.exec();
MessageBox mb(this, tr["Do you want to delete the log file?"], "icons/ebook.png");
mb.setButton(ACTION_B, tr["Yes"]);
mb.setButton(ACTION_X, tr["No"]);
if (mb.exec() == ACTION_B) {
mb.setButton(ACCEPT, tr["Yes"]);
mb.setButton(CLEAR, tr["No"]);
if (mb.exec() == ACCEPT) {
ledOn();
unlink(logfile.c_str());
sync();
@ -865,11 +865,13 @@ void GMenu2X::main() {
drawScrollBar(linkRows,menu->sectionLinks()->size()/linkColumns + ((menu->sectionLinks()->size()%linkColumns==0) ? 0 : 1),menu->firstDispRow(),43,resY-81);
/*
switch(volumeMode) {
case VOLUME_MODE_MUTE: sc.skinRes("imgs/mute.png")->blit(s,279,bottomBarIconY); break;
case VOLUME_MODE_PHONES: sc.skinRes("imgs/phones.png")->blit(s,279,bottomBarIconY); break;
default: sc.skinRes("imgs/volume.png")->blit(s,279,bottomBarIconY); break;
}
*/
if (menu->selLink()!=NULL) {
s->write ( font, menu->selLink()->getDescription(), halfX, resY-19, SFontHAlignCenter, SFontVAlignBottom );
@ -902,8 +904,6 @@ void GMenu2X::main() {
//s->write( font, tr[batstr.c_str()], 20, 170 );
//On Screen Help
if(input[ACTION_A] )
helpDisplayed = ! helpDisplayed;
if (helpDisplayed) {
s->box(10,50,300,143, skinConfColors[COLOR_MESSAGE_BOX_BG]);
@ -965,13 +965,55 @@ void GMenu2X::main() {
}
//#ifdef TARGET_GP2X
switch (input.waitForPressedButton()) {
case ACCEPT:
if (menu->selLink() != NULL) menu->selLink()->run();
break;
case CANCEL:
helpDisplayed = ! helpDisplayed;
break;
case SETTINGS:
options();
break;
case MENU:
contextMenu();
break;
case UP:
menu->linkUp();
break;
case DOWN:
menu->linkDown();
break;
case LEFT:
menu->linkLeft();
break;
case RIGHT:
menu->linkRight();
break;
case MANUAL:
menu->selLinkApp()->showManual();
break;
case ALTLEFT:
menu->decSectionIndex();
offset = menu->sectionLinks()->size()>linksPerPage ? 2 : 6;
break;
case ALTRIGHT:
menu->incSectionIndex();
offset = menu->sectionLinks()->size()>linksPerPage ? 2 : 6;
break;
default:
break;
}
/*
while (!input.update())
usleep(LOOP_DELAY);
if ( input[ACTION_B] && menu->selLink()!=NULL ) menu->selLink()->run();
else if ( input[ACTION_START] ) options();
else if ( input[ACTION_SELECT] ) contextMenu();
if ( input[ACCEPT] && menu->selLink()!=NULL ) menu->selLink()->run();
else if ( input[SETTINGS] ) options();
else if ( input[MENU] ) contextMenu();
// VOLUME SCALE MODIFIER
else if ( fwType=="open2x" && input[ACTION_X] ) {
else if ( fwType=="open2x" && input[CLEAR] ) {
volumeMode = constrain(volumeMode-1, -VOLUME_MODE_MUTE-1, VOLUME_MODE_NORMAL);
if(volumeMode < VOLUME_MODE_MUTE)
volumeMode = VOLUME_MODE_NORMAL;
@ -983,42 +1025,43 @@ void GMenu2X::main() {
setVolume(confInt["globalVolume"]);
}
// LINK NAVIGATION
else if ( input[ACTION_LEFT ] ) menu->linkLeft();
else if ( input[ACTION_RIGHT] ) menu->linkRight();
else if ( input[ACTION_UP ] ) menu->linkUp();
else if ( input[ACTION_DOWN ] ) menu->linkDown();
else if ( input[ALTLEFTEFT ] ) menu->linkLeft();
else if ( input[ALTRIGHTIGHT] ) menu->linkRight();
else if ( input[UP ] ) menu->linkUp();
else if ( input[DOWN ] ) menu->linkDown();
// SELLINKAPP SELECTED
else if (menu->selLinkApp()!=NULL) {
if ( input[ACTION_Y] ) menu->selLinkApp()->showManual();
else if ( input.isActive(ACTION_A) ) {
if ( input[MANUAL] ) menu->selLinkApp()->showManual();
else if ( input.isActive(CANCEL) ) {
// VOLUME
if ( input[ACTION_VOLDOWN] && !input.isActive(ACTION_VOLUP) )
if ( input[VOLDOWN] && !input.isActive(VOLUP) )
menu->selLinkApp()->setVolume( constrain(menu->selLinkApp()->volume()-1,0,100) );
if ( input[ACTION_VOLUP] && !input.isActive(ACTION_VOLDOWN) )
if ( input[VOLUP] && !input.isActive(VOLDOWN) )
menu->selLinkApp()->setVolume( constrain(menu->selLinkApp()->volume()+1,0,100) );;
if ( input.isActive(ACTION_VOLUP) && input.isActive(ACTION_VOLDOWN) ) menu->selLinkApp()->setVolume(-1);
if ( input.isActive(VOLUP) && input.isActive(VOLDOWN) ) menu->selLinkApp()->setVolume(-1);
} else {
// CLOCK
if ( input[ACTION_VOLDOWN] && !input.isActive(ACTION_VOLUP) )
if ( input[VOLDOWN] && !input.isActive(VOLUP) )
menu->selLinkApp()->setClock( constrain(menu->selLinkApp()->clock()-1,200,confInt["maxClock"]) );
if ( input[ACTION_VOLUP] && !input.isActive(ACTION_VOLDOWN) )
if ( input[VOLUP] && !input.isActive(VOLDOWN) )
menu->selLinkApp()->setClock( constrain(menu->selLinkApp()->clock()+1,200,confInt["maxClock"]) );
if ( input.isActive(ACTION_VOLUP) && input.isActive(ACTION_VOLDOWN) ) menu->selLinkApp()->setClock(336);
if ( input.isActive(VOLUP) && input.isActive(VOLDOWN) ) menu->selLinkApp()->setClock(336);
}
}
if ( input.isActive(ACTION_A) ) {
if (input.isActive(ACTION_L) && input.isActive(ACTION_R))
if ( input.isActive(CANCEL) ) {
if (input.isActive(ALTLEFT) && input.isActive(ALTRIGHT))
saveScreenshot();
} else {
// SECTIONS
if ( input[ACTION_L ] ) {
if ( input[ALTLEFT ] ) {
menu->decSectionIndex();
offset = menu->sectionLinks()->size()>linksPerPage ? 2 : 6;
} else if ( input[ACTION_R ] ) {
} else if ( input[ALTRIGHT ] ) {
menu->incSectionIndex();
offset = menu->sectionLinks()->size()>linksPerPage ? 2 : 6;
}
}
*/
}
}
@ -1213,6 +1256,7 @@ void GMenu2X::setSkin(const string &skin, bool setWallpaper) {
initFont();
}
/*
void GMenu2X::activateSdUsb() {
if (usbnet) {
MessageBox mb(this,tr["Operation not permitted."]+"\n"+tr["You should disable Usb Networking to do this."]);
@ -1220,7 +1264,7 @@ void GMenu2X::activateSdUsb() {
} else {
system("scripts/usbon.sh sd");
MessageBox mb(this,tr["USB Enabled (SD)"],"icons/usb.png");
mb.setButton(ACTION_B, tr["Turn off"]);
mb.setButton(ACCEPT, tr["Turn off"]);
mb.exec();
system("scripts/usboff.sh sd");
}
@ -1233,7 +1277,7 @@ void GMenu2X::activateNandUsb() {
} else {
system("scripts/usbon.sh nand");
MessageBox mb(this,tr["USB Enabled (Nand)"],"icons/usb.png");
mb.setButton(ACTION_B, tr["Turn off"]);
mb.setButton(ACCEPT, tr["Turn off"]);
mb.exec();
system("scripts/usboff.sh nand");
}
@ -1246,12 +1290,12 @@ void GMenu2X::activateRootUsb() {
} else {
system("scripts/usbon.sh root");
MessageBox mb(this,tr["USB Enabled (Root)"],"icons/usb.png");
mb.setButton(ACTION_B, tr["Turn off"]);
mb.setButton(ACCEPT, tr["Turn off"]);
mb.exec();
system("scripts/usboff.sh root");
}
}
*/
void GMenu2X::contextMenu() {
vector<MenuOption> voices;
{
@ -1307,6 +1351,8 @@ void GMenu2X::contextMenu() {
bg.box(0, 0, resX, resY, 0,0,0,150);
bg.box(box.x, box.y, box.w, box.h, skinConfColors["messageBoxBg"]);
bg.rectangle( box.x+2, box.y+2, box.w-4, box.h-4, skinConfColors["messageBoxBorder"] );*/
bevent_t event;
while (!close) {
tickNow = SDL_GetTicks();
@ -1354,11 +1400,30 @@ void GMenu2X::contextMenu() {
}
}
input.update();
if ( input[ACTION_SELECT] ) close = true;
if ( input[ACTION_UP ] ) sel = max(0, sel-1);
if ( input[ACTION_DOWN ] ) sel = min((int)voices.size()-1, sel+1);
if ( input[ACTION_B] ) { voices[sel].action(); close = true; }
if (fadeAlpha < 200) {
if (!input.pollEvent(&event) || event.state != PRESSED) continue;
} else {
event.button = input.waitForPressedButton();
}
switch(event.button) {
case MENU:
close = true;
break;
case UP:
sel = max(0, sel-1);
break;
case DOWN:
sel = min((int)voices.size()-1, sel+1);
break;
case ACCEPT:
voices[sel].action();
close = true;
break;
default:
break;
}
}
}
@ -1499,9 +1564,9 @@ void GMenu2X::editLink() {
void GMenu2X::deleteLink() {
if (menu->selLinkApp()!=NULL) {
MessageBox mb(this, tr.translate("Deleting $1",menu->selLink()->getTitle().c_str(),NULL)+"\n"+tr["Are you sure?"], menu->selLink()->getIconPath());
mb.setButton(ACTION_B, tr["Yes"]);
mb.setButton(ACTION_X, tr["No"]);
if (mb.exec() == ACTION_B) {
mb.setButton(ACCEPT, tr["Yes"]);
mb.setButton(CLEAR, tr["No"]);
if (mb.exec() == ACCEPT) {
ledOn();
menu->deleteSelectedLink();
sync();
@ -1561,9 +1626,9 @@ void GMenu2X::renameSection() {
void GMenu2X::deleteSection() {
MessageBox mb(this,tr["You will lose all the links in this section."]+"\n"+tr["Are you sure?"]);
mb.setButton(ACTION_B, tr["Yes"]);
mb.setButton(ACTION_X, tr["No"]);
if (mb.exec() == ACTION_B) {
mb.setButton(ACCEPT, tr["Yes"]);
mb.setButton(CLEAR, tr["No"]);
if (mb.exec() == ACCEPT) {
ledOn();
if (rmtree(path+"sections/"+menu->selSection())) {
menu->deleteSelectedSection();
@ -1655,12 +1720,22 @@ void GMenu2X::scanner() {
ledOff();
#endif
bool close = false;
while (!close) {
input.update();
if (input[ACTION_START] || input[ACTION_B] || input[ACTION_X]) close = true;
usleep(30000);
}
buttontype_t button;
do {
button = input.waitForPressedButton();
} while ((button != SETTINGS)
&& (button != ACCEPT)
&& (button != CLEAR));
/*
bevent_t event;
do {
input.getEvent(&event, true);
} while ((event.state != PRESSED) ||
( (event.button != SETTINGS)
&& (event.button != ACCEPT)
&& (event.button != CLEAR)));
*/
}
void GMenu2X::scanPath(string path, vector<string> *files) {
@ -1754,18 +1829,20 @@ unsigned short GMenu2X::getBatteryLevel() {
}
void GMenu2X::setInputSpeed() {
/*
input.setInterval(150);
input.setInterval(30, ACTION_VOLDOWN);
input.setInterval(30, ACTION_VOLUP );
input.setInterval(30, ACTION_A );
input.setInterval(500, ACTION_START );
input.setInterval(500, ACTION_SELECT );
input.setInterval(300, ACTION_X );
input.setInterval(300, ACTION_Y );
input.setInterval(1000,ACTION_B );
input.setInterval(30, VOLDOWN);
input.setInterval(30, VOLUP );
input.setInterval(30, CANCEL );
input.setInterval(500, SETTINGS );
input.setInterval(500, MENU );
input.setInterval(300, CLEAR );
input.setInterval(300, MANUAL );
input.setInterval(1000,ACCEPT );
//joy.setInterval(1000,ACTION_CLICK );
input.setInterval(300, ACTION_L );
input.setInterval(300, ACTION_R );
input.setInterval(300, ALTLEFT );
input.setInterval(300, ALTRIGHT );
*/
SDL_EnableKeyRepeat(1,150);
}

View File

@ -164,6 +164,43 @@ bool InputDialog::exec() {
action = drawVirtualKeyboard();
gmenu2x->s->flip();
switch (inputMgr.waitForPressedButton()) {
case SETTINGS:
ok = false;
close = true;
break;
case UP:
selRow--;
break;
case DOWN:
selRow++;
if (selRow==(int)kb->size()) selCol = selCol<8 ? 0 : 1;
break;
case LEFT:
selCol--;
break;
case RIGHT:
selCol++;
break;
case ACCEPT:
confirm();
break;
case MANUAL:
changeKeys();
break;
case CLEAR:
case ALTLEFT:
backspace();
break;
case ALTRIGHT:
space();
break;
default:
break;
}
/*
inputMgr.update();
if ( inputMgr[ACTION_START] ) action = ID_ACTION_CLOSE;
if ( inputMgr[ACTION_UP ] ) action = ID_ACTION_UP;
@ -198,6 +235,7 @@ bool InputDialog::exec() {
case ID_ACTION_KB_CHANGE: changeKeys(); break;
case ID_ACTION_SELECT: confirm(); break;
}
*/
}
return ok;

View File

@ -18,186 +18,167 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <iostream>
#include <sstream>
#include <fstream>
#include "debug.h"
#include "inputmanager.h"
#include "utilities.h"
#include "debug.h"
using namespace std;
#include <iostream>
#include <fstream>
InputManager::InputManager() {}
InputManager::~InputManager() {
for (uint x=0; x<joysticks.size(); x++)
if(SDL_JoystickOpened(x))
SDL_JoystickClose(joysticks[x]);
}
static SDL_Joystick *joystick;
void InputManager::init(const string &conffile) {
SDL_JoystickEventState(SDL_IGNORE);
int numJoy = SDL_NumJoysticks();
for (int x=0; x<numJoy; x++) {
SDL_Joystick *joy = SDL_JoystickOpen(x);
if (joy) {
INFO("Initialized joystick: '%s'\n", SDL_JoystickName(x));
joysticks.push_back(joy);
}
else WARNING("Failed to initialize joystick: %i\n", x);
}
setActionsCount(14);
if (fileExists(conffile)) {
ifstream inf(conffile.c_str(), ios_base::in);
if (inf.is_open()) {
string line, name, value;
stringstream ss;
string::size_type pos;
vector<string> values;
while (getline(inf, line, '\n')) {
pos = line.find("=");
name = trim(line.substr(0,pos));
value = trim(line.substr(pos+1,line.length()));
int action = -1;
if (name=="up") action = ACTION_UP;
else if (name=="down") action = ACTION_DOWN;
else if (name=="left") action = ACTION_LEFT;
else if (name=="right") action = ACTION_RIGHT;
else if (name=="a") action = ACTION_A;
else if (name=="b") action = ACTION_B;
else if (name=="x") action = ACTION_X;
else if (name=="y") action = ACTION_Y;
else if (name=="l") action = ACTION_L;
else if (name=="r") action = ACTION_R;
else if (name=="start") action = ACTION_START;
else if (name=="select") action = ACTION_SELECT;
else if (name=="volup") action = ACTION_VOLUP;
else if (name=="voldown") action = ACTION_VOLDOWN;
if (action >= 0) {
split(values, value, ",");
if (values.size() >= 2) {
if (values[0] == "joystickbutton" && values.size()==3) {
InputMap map;
map.type = InputManager::MAPPING_TYPE_BUTTON;
map.num = atoi(values[1].c_str());
map.value = atoi(values[2].c_str());
map.treshold = 0;
mappings[action].push_back(map);
} else if (values[0] == "joystickaxys" && values.size()==4) {
InputMap map;
map.type = InputManager::MAPPING_TYPE_AXYS;
map.num = atoi(values[1].c_str());
map.value = atoi(values[2].c_str());
map.treshold = atoi(values[3].c_str());
mappings[action].push_back(map);
} else if (values[0] == "keyboard") {
InputMap map;
map.type = InputManager::MAPPING_TYPE_KEYPRESS;
map.value = atoi(values[1].c_str());
mappings[action].push_back(map);
}
}
}
}
inf.close();
}
}
if (!readConfFile(conffile))
ERROR("InputManager initialization from config file failed.\n");
}
void InputManager::setActionsCount(int count) {
actions.clear();
actionTick.clear();
interval.clear();
for (int x=0; x<count; x++) {
actions.push_back(false);
actionTick.push_back(0);
interval.push_back(0);
MappingList maplist;
mappings.push_back(maplist);
}
InputManager::InputManager() {
initJoystick();
}
bool InputManager::update() {
bool anyactions = false;
SDL_JoystickUpdate();
events.clear();
SDL_Event event;
while (SDL_PollEvent(&event)) {
SDL_Event evcopy = event;
events.push_back(evcopy);
}
Uint32 tick = SDL_GetTicks();
for (uint x=0; x<actions.size(); x++) {
actions[x] = false;
if (isActive(x)) {
if (tick-actionTick[x]>interval[x]) {
actions[x] = true;
actionTick[x] = tick;
anyactions = true;
}
} else {
actionTick[x] = 0;
}
}
return anyactions;
InputManager::~InputManager() {
if (SDL_NumJoysticks > 0)
SDL_JoystickClose(joystick);
}
int InputManager::count() {
return actions.size();
void InputManager::initJoystick() {
if (SDL_NumJoysticks > 0)
joystick = SDL_JoystickOpen(0);
}
void InputManager::setInterval(int ms, int action) {
if (action<0)
for (uint x=0; x<interval.size(); x++)
interval[x] = ms;
else if ((uint)action < interval.size())
interval[action] = ms;
bool InputManager::readConfFile(const string &conffile) {
if (!fileExists(conffile)) return false;
ifstream inf(conffile.c_str(), ios_base::in);
if (!(inf.is_open()))
return false;
string line, name, source;
string::size_type pos;
buttontype_t button;
while(getline(inf, line, '\n')) {
pos = line.find("=");
name = trim(line.substr(0,pos));
line = trim(line.substr(pos+1,line.length()));
if (name == "up") button = UP;
else if (name == "down") button = DOWN;
else if (name == "left") button = LEFT;
else if (name == "right") button = RIGHT;
else if (name == "accept") button = ACCEPT;
else if (name == "cancel") button = CANCEL;
else if (name == "clear") button = CLEAR;
else if (name == "manual") button = MANUAL;
else if (name == "altleft") button = ALTLEFT;
else if (name == "altright") button = ALTRIGHT;
else if (name == "menu") button = MENU;
else if (name == "settings") button = SETTINGS;
else if (name == "volup") button = VOLUP;
else if (name == "voldown") button = VOLDOWN;
else if (name == "power") button = POWER;
else if (name == "lock") button = LOCK;
else return false;
pos = line.find(",");
source = trim(line.substr(0,pos));
line = trim(line.substr(pos+1, line.length()));
if (source == "keyboard") ButtonMap[button].source = KEYBOARD;
else if (source == "joystick") ButtonMap[button].source = JOYSTICK;
else return false;
ButtonMap[button].code = atoi(line.c_str());
}
inf.close();
return true;
}
bool InputManager::operator[](int action) {
if (action<0 || (uint)action>=actions.size()) return false;
return actions[action];
buttontype_t InputManager::waitForPressedButton() {
return waitForButton(PRESSED);
}
bool InputManager::isActive(int action) {
MappingList mapList = mappings[action];
for (MappingList::const_iterator it = mapList.begin(); it !=mapList.end(); ++it) {
InputMap map = *it;
switch (map.type) {
case InputManager::MAPPING_TYPE_BUTTON:
if (map.num < joysticks.size() && SDL_JoystickGetButton(joysticks[map.num], map.value))
return true;
break;
case InputManager::MAPPING_TYPE_AXYS:
if (map.num < joysticks.size()) {
int axyspos = SDL_JoystickGetAxis(joysticks[map.num], map.value);
if (map.treshold<0 && axyspos < map.treshold) return true;
if (map.treshold>0 && axyspos > map.treshold) return true;
}
break;
case InputManager::MAPPING_TYPE_KEYPRESS:
for (uint ex=0; ex<events.size(); ex++) {
if (events[ex].type == SDL_KEYDOWN && events[ex].key.keysym.sym == map.value)
return true;
}
break;
}
}
return false;
buttontype_t InputManager::waitForReleasedButton() {
return waitForButton(RELEASED);
}
buttontype_t InputManager::waitForButton(enum state_e state) {
bevent_t event;
do {
waitForEvent(&event);
} while(event.state != state);
return event.button;
}
void InputManager::waitForEvent(bevent_t *event) {
getEvent(event, true);
}
bool InputManager::pollEvent(bevent_t *event) {
return getEvent(event, false);
}
bool InputManager::getEvent(bevent_t *bevent, bool wait) {
//TODO: when an event is processed, program a new event
//in some time, and when it occurs, do a key repeat
SDL_JoystickUpdate();
SDL_Event event;
if (wait)
SDL_WaitEvent(&event);
else {
bevent->state = RELEASED;
if (!SDL_PollEvent(&event)) return false;
}
enum source_type_e source;
switch(event.type) {
case SDL_KEYDOWN:
bevent->state = PRESSED;
source = KEYBOARD;
break;
case SDL_KEYUP:
bevent->state = RELEASED;
source = KEYBOARD;
break;
case SDL_JOYBUTTONDOWN:
bevent->state = PRESSED;
source = JOYSTICK;
break;
case SDL_JOYBUTTONUP:
bevent->state = RELEASED;
source = JOYSTICK;
break;
default:
return false;
break;
}
if (source == KEYBOARD) {
for (int i=0; i<BUTTONTYPE_T_SIZE; i++)
if (ButtonMap[i].source == KEYBOARD && (unsigned int)event.key.keysym.sym == ButtonMap[i].code) {
bevent->button = (buttontype_t)i;
break;
}
} else {
for (int i=0; i<BUTTONTYPE_T_SIZE; i++)
if (ButtonMap[i].source == JOYSTICK && (unsigned int)event.jbutton.button == ButtonMap[i].code) {
bevent->button = (buttontype_t)i;
break;
}
}
return true;
}

View File

@ -17,73 +17,57 @@
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef INPUTMANAGER_H
#define INPUTMANAGER_H
#ifndef NEWINPUT_H
#define NEWINPUT_H
#define ACTION_UP 0
#define ACTION_DOWN 1
#define ACTION_LEFT 2
#define ACTION_RIGHT 3
#define ACTION_A 4
#define ACTION_B 5
#define ACTION_X 6
#define ACTION_Y 7
#define ACTION_L 8
#define ACTION_R 9
#define ACTION_START 10
#define ACTION_SELECT 11
#define ACTION_VOLUP 12
#define ACTION_VOLDOWN 13
#include <SDL/SDL.h>
#include <sstream>
#include <SDL.h>
#include <SDL_image.h>
#include <vector>
#include <string>
using namespace std;
using std::vector;
using std::string;
typedef enum buttontype_e {
UP, DOWN, LEFT, RIGHT,
ACCEPT, CANCEL,
CLEAR, MANUAL,
ALTLEFT, ALTRIGHT,
MENU, SETTINGS,
VOLUP, VOLDOWN,
POWER, LOCK
} buttontype_t;
#define BUTTONTYPE_T_SIZE 16
enum source_type_e {KEYBOARD, JOYSTICK};
enum state_e {PRESSED, RELEASED};
typedef struct {
int type;
uint num;
int value;
int treshold;
} InputMap;
source_type_e source;
Uint32 code;
} input_t;
typedef struct {
buttontype_t button;
state_e state;
} bevent_t;
typedef vector<InputMap> MappingList;
typedef vector<SDL_Event> SDLEventList;
/**
Manages all input peripherals
@author Massimiliano Torromeo <massimiliano.torromeo@gmail.com>
*/
class InputManager {
private:
InputMap getInputMapping(int action);
vector<Uint32> actionTick;
vector<Uint32> interval;
SDLEventList events;
input_t ButtonMap[BUTTONTYPE_T_SIZE];
vector <SDL_Joystick*> joysticks;
vector<bool> actions;
vector<MappingList> mappings;
bool readConfFile(const string &conffile);
void initJoystick();
bool getEvent(bevent_t *bevent, bool wait);
buttontype_t waitForButton(enum state_e state);
public:
static const int MAPPING_TYPE_UNDEFINED = -1;
static const int MAPPING_TYPE_BUTTON = 0;
static const int MAPPING_TYPE_AXYS = 1;
static const int MAPPING_TYPE_KEYPRESS = 2;
InputManager();
~InputManager();
InputManager();
~InputManager();
void init(const string &conffile = "input.conf");
bool update();
int count();
void setActionsCount(int count);
void setInterval(int ms, int action = -1);
bool operator[](int action);
bool isActive(int action);
void init(const string &conffile);
void waitForEvent(bevent_t *event);
buttontype_t waitForPressedButton();
buttontype_t waitForReleasedButton();
bool pollEvent(bevent_t *event);
};
#endif

View File

@ -333,11 +333,28 @@ void LinkApp::showManual() {
repaint = false;
}
inputMgr.update();
if ( inputMgr[ACTION_Y] || inputMgr[ACTION_X] || inputMgr[ACTION_START] ) close = true;
if ( inputMgr[ACTION_LEFT] && page>0 ) { page--; repaint=true; }
if ( inputMgr[ACTION_RIGHT] && page<pagecount-1 ) { page++; repaint=true; }
}
switch(inputMgr.waitForPressedButton()) {
case MANUAL:
case CLEAR:
case SETTINGS:
close = true;
break;
case LEFT:
if (page > 0) {
page--;
repaint = true;
}
break;
case RIGHT:
if (page < pagecount-1) {
page++;
repaint=true;
}
break;
default:
break;
}
}
return;
}

View File

@ -21,6 +21,7 @@
#define MENUSETTING_H
#include "buttonbox.h"
#include "inputmanager.h"
#include <string>
@ -46,7 +47,7 @@ public:
virtual void draw(int y);
virtual void handleTS();
virtual void manageInput() = 0;
virtual void manageInput(bevent_t *event) = 0;
virtual void adjustInput();
virtual void drawSelected(int y);
virtual bool edited() = 0;

View File

@ -64,10 +64,10 @@ void MenuSettingBool::draw(int y)
gmenu2x->s->write( gmenu2x->font, strvalue, 155, y+gmenu2x->font->getHalfHeight(), SFontHAlignLeft, SFontVAlignMiddle );
}
void MenuSettingBool::manageInput()
void MenuSettingBool::manageInput(bevent_t *event)
{
if (gmenu2x->input[ACTION_B])
toggle();
if (event->button == ACCEPT && event->state == PRESSED)
toggle();
}
void MenuSettingBool::toggle()

View File

@ -21,6 +21,7 @@
#define MENUSETTINGBOOL_H
#include "menusetting.h"
#include "inputmanager.h"
class GMenu2X;
@ -44,7 +45,7 @@ public:
virtual ~MenuSettingBool() {}
virtual void draw(int y);
virtual void manageInput();
virtual void manageInput(bevent_t *event);
virtual bool edited();
void setValue(int value);

View File

@ -65,12 +65,18 @@ void MenuSettingInt::draw(int y)
gmenu2x->s->write( gmenu2x->font, strvalue, 155, y+gmenu2x->font->getHalfHeight(), SFontHAlignLeft, SFontVAlignMiddle );
}
void MenuSettingInt::manageInput()
void MenuSettingInt::manageInput(bevent_t *event)
{
if (gmenu2x->input[ACTION_LEFT ] || gmenu2x->input[ACTION_X])
dec();
if (gmenu2x->input[ACTION_RIGHT] || gmenu2x->input[ACTION_Y])
inc();
switch (event->button) {
case LEFT:
dec();
break;
case RIGHT:
inc();
break;
default:
break;
}
}
void MenuSettingInt::inc()
@ -100,8 +106,8 @@ int MenuSettingInt::value()
void MenuSettingInt::adjustInput()
{
#ifdef TARGET_GP2X
gmenu2x->input.setInterval(30, ACTION_LEFT );
gmenu2x->input.setInterval(30, ACTION_RIGHT);
// gmenu2x->input.setInterval(30, ACTION_LEFT );
// gmenu2x->input.setInterval(30, ACTION_RIGHT);
#endif
}

View File

@ -21,6 +21,7 @@
#define MENUSETTINGINT_H
#include "menusetting.h"
#include "inputmanager.h"
class MenuSettingInt : public MenuSetting {
private:
@ -38,7 +39,7 @@ public:
const std::string &description, int *value, int min, int max);
virtual ~MenuSettingInt() {}
virtual void manageInput();
virtual void manageInput(bevent_t *event);
virtual void adjustInput();
virtual void draw(int);
virtual bool edited();

View File

@ -49,10 +49,18 @@ MenuSettingMultiString::MenuSettingMultiString(
buttonBox.add(btn);
}
void MenuSettingMultiString::manageInput()
void MenuSettingMultiString::manageInput(bevent_t *event)
{
if (gmenu2x->input[ACTION_LEFT ]) decSel();
if (gmenu2x->input[ACTION_RIGHT]) incSel();
switch(event->button) {
case LEFT:
decSel();
break;
case RIGHT:
incSel();
break;
default:
break;
}
}
void MenuSettingMultiString::incSel()

View File

@ -21,6 +21,7 @@
#define MENUSETTINGMULTISTRING_H
#include "menusettingstringbase.h"
#include "inputmanager.h"
#include <vector>
@ -44,7 +45,7 @@ public:
const std::vector<std::string> *choices);
virtual ~MenuSettingMultiString() {};
virtual void manageInput();
virtual void manageInput(bevent_t *event);
};
#endif

View File

@ -82,15 +82,23 @@ void MenuSettingRGBA::handleTS() {
MenuSetting::handleTS();
}
void MenuSettingRGBA::manageInput() {
if (gmenu2x->input[ACTION_Y])
inc();
if (gmenu2x->input[ACTION_X])
dec();
if (gmenu2x->input[ACTION_LEFT])
leftComponent();
if (gmenu2x->input[ACTION_RIGHT])
rightComponent();
void MenuSettingRGBA::manageInput(bevent_t *event) {
switch(event->button) {
case MANUAL:
inc();
break;
case CLEAR:
dec();
break;
case LEFT:
leftComponent();
break;
case RIGHT:
rightComponent();
break;
default:
break;
}
}
void MenuSettingRGBA::dec()
@ -173,9 +181,11 @@ unsigned short MenuSettingRGBA::getSelPart()
void MenuSettingRGBA::adjustInput()
{
#ifdef TARGET_GP2X
/*
gmenu2x->input.setInterval(30, ACTION_Y );
gmenu2x->input.setInterval(30, ACTION_X );
gmenu2x->input.setInterval(30, ACTION_L );
*/
#endif
}

View File

@ -22,6 +22,7 @@
#include "menusetting.h"
#include "surface.h"
#include "inputmanager.h"
class GMenu2X;
@ -46,7 +47,7 @@ public:
virtual void draw(int y);
virtual void handleTS();
virtual void manageInput();
virtual void manageInput(bevent_t *event);
virtual void adjustInput();
virtual void drawSelected(int y);
virtual bool edited();

View File

@ -44,10 +44,18 @@ void MenuSettingStringBase::draw(int y)
SFontHAlignLeft, SFontVAlignMiddle);
}
void MenuSettingStringBase::manageInput()
void MenuSettingStringBase::manageInput(bevent_t *event)
{
if (gmenu2x->input[ACTION_X]) clear();
if (gmenu2x->input[ACTION_B]) edit();
switch (event->button) {
case CLEAR:
clear();
break;
case ACCEPT:
edit();
break;
default:
break;
}
}
void MenuSettingStringBase::clear()

View File

@ -21,6 +21,7 @@
#define MENUSETTINGSTRINGBASE_H
#include "menusetting.h"
#include "inputmanager.h"
class MenuSettingStringBase : public MenuSetting {
protected:
@ -37,7 +38,7 @@ public:
virtual ~MenuSettingStringBase();
virtual void draw(int y);
virtual void manageInput();
virtual void manageInput(bevent_t *event);
virtual bool edited();
void setValue(const std::string &value) { *_value = value; }

View File

@ -40,23 +40,23 @@ MessageBox::MessageBox(GMenu2X *gmenu2x, const string &text, const string &icon)
}
//Default enabled button
buttons[ACTION_B] = "OK";
buttons[ACCEPT] = "OK";
//Default labels
buttonLabels[ACTION_UP] = "up";
buttonLabels[ACTION_DOWN] = "down";
buttonLabels[ACTION_LEFT] = "left";
buttonLabels[ACTION_RIGHT] = "right";
buttonLabels[ACTION_A] = "a";
buttonLabels[ACTION_B] = "b";
buttonLabels[ACTION_X] = "x";
buttonLabels[ACTION_Y] = "y";
buttonLabels[ACTION_L] = "l";
buttonLabels[ACTION_R] = "r";
buttonLabels[ACTION_START] = "start";
buttonLabels[ACTION_SELECT] = "select";
buttonLabels[ACTION_VOLUP] = "vol+";
buttonLabels[ACTION_VOLDOWN] = "vol-";
buttonLabels[UP] = "up";
buttonLabels[DOWN] = "down";
buttonLabels[LEFT] = "left";
buttonLabels[RIGHT] = "right";
buttonLabels[CANCEL] = "a";
buttonLabels[ACCEPT] = "b";
buttonLabels[CLEAR] = "x";
buttonLabels[MANUAL] = "y";
buttonLabels[ALTLEFT] = "l";
buttonLabels[ALTRIGHT] = "r";
buttonLabels[SETTINGS] = "start";
buttonLabels[MENU] = "select";
buttonLabels[VOLUP] = "vol+";
buttonLabels[VOLDOWN] = "vol-";
}
void MessageBox::setButton(int action, const string &btn) {
@ -102,6 +102,7 @@ int MessageBox::exec() {
bg.blit(gmenu2x->s,0,0);
gmenu2x->s->flip();
bevent_t event;
while (result<0) {
//touchscreen
if (gmenu2x->f200) {
@ -113,11 +114,15 @@ int MessageBox::exec() {
}
}
}
/*
gmenu2x->input.update();
for (uint i=0; i<buttons.size(); i++)
if (buttons[i]!="" && gmenu2x->input[i]) result = i;
*/
if (gmenu2x->input.pollEvent(&event) && (event.state == PRESSED) && (buttons[event.button] != "")) result = event.button;
usleep(LOOP_DELAY);
}

View File

@ -115,7 +115,65 @@ int Selector::exec(int startSelection) {
gmenu2x->drawScrollBar(SELECTOR_ELEMENTS,fl.size(),firstElement,42,175);
gmenu2x->s->flip();
switch (gmenu2x->input.waitForPressedButton()) {
case SETTINGS:
close = true;
result = false;
break;
case UP:
if (selected == 0) selected = fl.size() -1;
else selected -= 1;
selTick = SDL_GetTicks();
break;
case ALTLEFT:
if ((int)(selected-SELECTOR_ELEMENTS+1)<0) selected = 0;
else selected -= SELECTOR_ELEMENTS-1;
selTick = SDL_GetTicks();
break;
case DOWN:
if (selected+1>=fl.size()) selected = 0;
else selected += 1;
selTick = SDL_GetTicks();
break;
case ALTRIGHT:
if (selected+SELECTOR_ELEMENTS-1>=fl.size()) selected = fl.size()-1;
else selected += SELECTOR_ELEMENTS-1;
selTick = SDL_GetTicks();
break;
case CLEAR:
if (link->getSelectorBrowser()) {
string::size_type p = dir.rfind("/", dir.size()-2);
if (p==string::npos || dir.compare(0, 1, "/") != 0 || dir.length() < 2) {
close = true;
result = false;
} else {
dir = dir.substr(0,p+1);
INFO("%s\n", dir.c_str());
selected = 0;
firstElement = 0;
prepare(&fl,&screens,&titles);
}
} else {
close = true;
result = false;
}
break;
case ACCEPT:
if (fl.isFile(selected)) {
file = fl[selected];
close = true;
} else {
dir = dir+fl[selected]+"/";
selected = 0;
firstElement = 0;
prepare(&fl,&screens,&titles);
}
break;
default:
break;
}
/*
gmenu2x->input.update();
if ( gmenu2x->input[ACTION_START] ) { close = true; result = false; }
if ( gmenu2x->input[ACTION_UP] ) {
@ -179,6 +237,7 @@ int Selector::exec(int startSelection) {
prepare(&fl,&screens,&titles);
}
}
*/
}
gmenu2x->sc.defaultAlpha = true;
freeScreenshots(&screens);

View File

@ -105,11 +105,39 @@ bool SettingsDialog::exec() {
gmenu2x->s->flip();
voices[sel]->handleTS();
bevent_t event;
do {
inputMgr.waitForEvent(&event);
} while (event.state != PRESSED);
switch (event.button) {
case SETTINGS:
close = true;
break;
case UP:
if (sel==0)
sel = voices.size()-1;
else
sel -= 1;
gmenu2x->setInputSpeed();
voices[sel]->adjustInput();
break;
case DOWN:
sel += 1;
if (sel>=voices.size()) sel = 0;
gmenu2x->setInputSpeed();
voices[sel]->adjustInput();
break;
default:
voices[sel]->manageInput(&event);
break;
}
/*
inputMgr.update();
if ( inputMgr[ACTION_START] ) action = SD_ACTION_CLOSE;
if ( inputMgr[ACTION_UP ] ) action = SD_ACTION_UP;
if ( inputMgr[ACTION_DOWN ] ) action = SD_ACTION_DOWN;
voices[sel]->manageInput();
switch (action) {
case SD_ACTION_CLOSE: close = true; break;
@ -128,6 +156,7 @@ bool SettingsDialog::exec() {
voices[sel]->adjustInput();
} break;
}
*/
}
gmenu2x->setInputSpeed();

View File

@ -116,7 +116,30 @@ void TextDialog::exec() {
drawText(text, firstRow, rowsPerPage);
gmenu2x->s->flip();
switch(gmenu2x->input.waitForPressedButton()) {
case UP:
if (firstRow > 0) firstRow--;
break;
case DOWN:
if (firstRow + rowsPerPage < text->size()) firstRow++;
break;
case ALTLEFT:
if (firstRow >= rowsPerPage-1) firstRow -= rowsPerPage-1;
else firstRow = 0;
break;
case ALTRIGHT:
if (firstRow + rowsPerPage*2 -1 < text->size()) firstRow += rowsPerPage-1;
else firstRow = max(0, text->size() - rowsPerPage);
break;
case SETTINGS:
case CLEAR:
close = true;
break;
default:
break;
}
/*
gmenu2x->input.update();
if ( gmenu2x->input[ACTION_UP ] && firstRow>0 ) firstRow--;
if ( gmenu2x->input[ACTION_DOWN] && firstRow+rowsPerPage<text->size() ) firstRow++;
@ -133,5 +156,6 @@ void TextDialog::exec() {
firstRow = max(0,text->size()-rowsPerPage);
}
if ( gmenu2x->input[ACTION_START] || gmenu2x->input[ACTION_X] ) close = true;
*/
}
}

View File

@ -86,6 +86,7 @@ void TextManualDialog::exec() {
string spagecount;
ss >> spagecount;
string pageStatus;
while (!close) {
bg.blit(gmenu2x->s,0,0);
writeSubTitle(pages[page].title);
@ -99,6 +100,42 @@ void TextManualDialog::exec() {
gmenu2x->s->flip();
switch(gmenu2x->input.waitForPressedButton()) {
case UP:
if (firstRow > 0) firstRow--;
break;
case DOWN:
if (firstRow + rowsPerPage < pages[page].text.size()) firstRow++;
break;
case LEFT:
if (page > 0) {
page--;
firstRow = 0;
}
break;
case RIGHT:
if (page < pages.size() -1) {
page++;
firstRow = 0;
}
break;
case ALTLEFT:
if (firstRow >= rowsPerPage-1) firstRow -= rowsPerPage-1;
else firstRow = 0;
break;
case ALTRIGHT:
if (firstRow + rowsPerPage*2 -1 < pages[page].text.size()) firstRow += rowsPerPage-1;
else firstRow = max(0, pages[page].text.size() - rowsPerPage);
break;
case SETTINGS:
case CLEAR:
close = true;
break;
default:
break;
}
/*
gmenu2x->input.update();
if ( gmenu2x->input[ACTION_UP ] && firstRow>0 ) firstRow--;
if ( gmenu2x->input[ACTION_DOWN ] && firstRow+rowsPerPage<pages[page].text.size() ) firstRow++;
@ -117,5 +154,6 @@ void TextManualDialog::exec() {
firstRow = max(0,pages[page].text.size()-rowsPerPage);
}
if ( gmenu2x->input[ACTION_START] || gmenu2x->input[ACTION_X] ) close = true;
*/
}
}

View File

@ -51,6 +51,7 @@ bool WallpaperDialog::exec()
DEBUG("Wallpapers: %i\n", wallpapers.size());
uint i, selected = 0, firstElement = 0, iY;
while (!close) {
if (selected>firstElement+9) firstElement=selected-9;
if (selected<firstElement) firstElement=selected;
@ -86,48 +87,39 @@ bool WallpaperDialog::exec()
gmenu2x->drawScrollBar(10,wallpapers.size(),firstElement,44,170);
gmenu2x->s->flip();
gmenu2x->input.update();
if ( gmenu2x->input[ACTION_SELECT] ) { close = true; result = false; }
if ( gmenu2x->input[ACTION_UP ] ) {
if (selected==0)
selected = wallpapers.size()-1;
else
selected -= 1;
}
if ( gmenu2x->input[ACTION_L ] ) {
if ((int)(selected-9)<0) {
selected = 0;
} else {
selected -= 9;
}
}
if ( gmenu2x->input[ACTION_DOWN ] ) {
if (selected+1>=wallpapers.size())
selected = 0;
else
selected += 1;
}
if ( gmenu2x->input[ACTION_R ] ) {
if (selected+9>=wallpapers.size()) {
selected = wallpapers.size()-1;
} else {
selected += 9;
}
}
if ( gmenu2x->input[ACTION_X] ) {
close = true;
result = false;
}
if ( gmenu2x->input[ACTION_B] ) {
close = true;
if (wallpapers.size()>0) {
if (selected<wallpapers.size()-fl.getFiles().size())
wallpaper = "skins/"+gmenu2x->confStr["skin"]+"/wallpapers/"+wallpapers[selected];
else
wallpaper = "skins/Default/wallpapers/"+wallpapers[selected];
} else result = false;
}
switch(gmenu2x->input.waitForPressedButton()) {
case MENU:
case CLEAR:
close = true;
result = false;
break;
case UP:
if (selected == 0) selected = wallpapers.size()-1;
else selected -= 1;
break;
case ALTLEFT:
if ((int)(selected-9) < 0) selected = 0;
else selected -= 9;
break;
case DOWN:
if (selected+1 >= wallpapers.size()) selected = 0;
else selected += 1;
break;
case ALTRIGHT:
if (selected+9 >= wallpapers.size()) selected = wallpapers.size()-1;
else selected += 9;
break;
case ACCEPT:
close = true;
if (wallpapers.size() > 0) {
if (selected < wallpapers.size() - fl.getFiles().size())
wallpaper = "skins/" + gmenu2x->confStr["skin"] + "/wallpapers/" + wallpapers[selected];
else
wallpaper = "skins/Default/wallpapers/" + wallpapers[selected];
} else result = false;
default:
break;
}
}
for (uint i=0; i<wallpapers.size(); i++)