enable the keyboard settings menu to handle multiple binds

This commit is contained in:
ac-stef
2016-08-26 14:31:58 +02:00
parent dbfdb5927b
commit ebd1c917dc
3 changed files with 58 additions and 26 deletions
+6 -3
View File
@@ -163,10 +163,13 @@ keym *findbind(const char *key)
return NULL;
}
keym *findbinda(const char *action, int type)
keym **findbinda(const char *action, int type)
{
loopv(keyms) if(!strcasecmp(keyms[i].actions[type], action)) return &keyms[i];
return NULL;
static vector<keym *> res;
res.setsize(0);
loopv(keyms) if(!strcasecmp(keyms[i].actions[type], action)) res.add(&keyms[i]);
res.add(NULL);
return res.getbuf();
}
keym *findbindc(int code)
+50 -22
View File
@@ -677,10 +677,14 @@ struct mitemkeyinput : mitem
{
char *text, *bindcmd;
const char *keyname;
vector<int> newkeys;
int isup, bindtype;
string keynames;
static const char *unknown, *empty;
bool capture;
mitemkeyinput(gmenu *parent, char *text, char *bindcmd, color *bgcolor) : mitem(parent, bgcolor, mitem::TYPE_KEYINPUT), text(text), bindcmd(bindcmd), keyname(NULL), capture(false) {};
mitemkeyinput(gmenu *parent, char *text, char *bindcmd, color *bgcolor) : mitem(parent, bgcolor, mitem::TYPE_KEYINPUT), text(text), bindcmd(bindcmd),
keyname(NULL), isup(0), bindtype(keym::ACTION_DEFAULT), capture(false) {};
~mitemkeyinput()
{
@@ -701,31 +705,54 @@ struct mitemkeyinput : mitem
virtual void init()
{
displaycurrentbind();
keynames[0] = 0;
for(keym **km = findbinda(bindcmd, bindtype); *km; km++) concatformatstring(keynames, " + %s", (*km)->name);
keyname = *keynames ? keynames + 3 : unknown;
capture = false;
}
virtual int select()
{
capture = true;
isup = 0;
keyname = empty;
newkeys.setsize(0);
keynames[0] = '\0';
return 0;
}
virtual void key(int code, bool isdown, int unicode)
{
if(!capture || code < -5 || code > SDLK_MENU) return;
keym *km;
while((km = findbinda(bindcmd))) { bindkey(km, ""); } // clear existing binds to this cmd
if(bindc(code, bindcmd)) parent->init(); // re-init all bindings
else conoutf("\f3could not bind key");
if(!capture || code < -5 || code > SDLK_MENU || !findbindc(code)) return;
if(code == SDLK_ESCAPE)
{
capture = false;
parent->init();
return;
}
bool known = newkeys.find(code) >= 0;
if(isdown)
{
if(!known)
{
newkeys.add(code);
concatformatstring(keynames, "%s + ", findbindc(code)->name);
keyname = keynames;
}
}
else
{
if(known && ++isup == newkeys.length())
{
for(keym **km = findbinda(bindcmd, bindtype); *km; km++) bindkey(*km, "", bindtype); // clear existing binds to this cmd
bool bindfailed = false;
loopv(newkeys) bindfailed = !bindc(newkeys[i], bindcmd, bindtype) || bindfailed;
if(bindfailed) conoutf("\f3could not bind key");
else parent->init(); // show new keys
}
}
}
void displaycurrentbind()
{
keym *km = findbinda(bindcmd);
keyname = km ? km->name : unknown;
}
};
const char *mitemkeyinput::unknown = "?";
@@ -1101,6 +1128,17 @@ bool menukey(int code, bool isdown, int unicode, SDLMod mod)
{
if(!curmenu) return false;
int n = curmenu->items.length(), menusel = curmenu->menusel;
if(curmenu->items.inrange(menusel))
{
mitem *m = curmenu->items[menusel];
if(m->mitemtype == mitem::TYPE_KEYINPUT && ((mitemkeyinput *)m)->capture)
{
m->key(code, isdown, unicode);
return true;
}
}
if(isdown)
{
bool hasdesc = false;
@@ -1108,16 +1146,6 @@ bool menukey(int code, bool isdown, int unicode, SDLMod mod)
//int pagesize = MAXMENU - (curmenu->header ? 2 : 0) - (curmenu->footer || hasdesc ? 2 : 0); // FIXME: footer-length
int pagesize = MAXMENU - (curmenu->header ? 2 : 0) - (curmenu->footer ? (curmenu->footlen?(curmenu->footlen+1):2) : (hasdesc ? 2 : 0)); // FIXME: footer-length
if(curmenu->items.inrange(menusel))
{
mitem *m = curmenu->items[menusel];
if(m->mitemtype == mitem::TYPE_KEYINPUT && ((mitemkeyinput *)m)->capture && code != SDLK_ESCAPE)
{
m->key(code, isdown, unicode);
return true;
}
}
switch(code)
{
case SDLK_PAGEUP: menusel -= pagesize; break;
+2 -1
View File
@@ -157,8 +157,9 @@ struct keym
extern keym *keypressed;
extern bool bindkey(keym *km, const char *action, int state = keym::ACTION_DEFAULT);
extern keym *findbinda(const char *action, int type = keym::ACTION_DEFAULT);
extern keym **findbinda(const char *action, int type = keym::ACTION_DEFAULT);
extern bool bindc(int code, const char *action, int type = keym::ACTION_DEFAULT);
extern keym *findbindc(int code);
// menus
extern void rendermenu();