allow buttons to be defined with arbitrary lua callbacks

This commit is contained in:
Tim Felgentreff 2015-10-28 14:24:09 +01:00
parent d819adf949
commit 4f4452dcc2
4 changed files with 34 additions and 13 deletions

View file

@ -76,7 +76,8 @@ enum ButtonCmd {
ButtonCancel, /// cancel
ButtonCancelUpgrade, /// cancel upgrade
ButtonCancelTrain, /// cancel training
ButtonCancelBuild /// cancel building
ButtonCancelBuild, /// cancel building
ButtonCallbackAction
};
class ButtonAction;
@ -86,7 +87,7 @@ typedef bool (*ButtonCheckFunc)(const CUnit &, const ButtonAction &);
class ButtonAction
{
public:
ButtonAction() : Pos(0), Level(0), AlwaysShow(false), Action(ButtonMove), Value(0),
ButtonAction() : Pos(0), Level(0), AlwaysShow(false), Action(ButtonMove), Value(0), Payload(NULL),
Allowed(NULL), Key(0) {}
int Pos; /// button position in the grid
@ -94,6 +95,7 @@ public:
bool AlwaysShow; /// button is always shown but drawn grayscale if not available
ButtonCmd Action; /// command on button press
int Value; /// extra value for command
void* Payload;
std::string ValueStr; /// keep original value string
ButtonCheckFunc Allowed; /// Check if this button is allowed
@ -266,7 +268,7 @@ extern void InitButtons();
extern void CleanButtons();
/// Make a new button
extern int AddButton(int pos, int level, const std::string &IconIdent,
ButtonCmd action, const std::string &value, const ButtonCheckFunc func,
ButtonCmd action, const std::string &value, void* payload, const ButtonCheckFunc func,
const std::string &arg, const int key, const std::string &hint, const std::string &descr,
const std::string &sound, const std::string &cursor, const std::string &umask,
const std::string &popup, bool alwaysShow);

View file

@ -293,6 +293,7 @@ private:
void DoClicked_Train(int button);
void DoClicked_UpgradeTo(int button);
void DoClicked_Research(int button);
void DoClicked_CallbackAction(int button);
public:

View file

@ -103,7 +103,7 @@ void InitButtons()
** FIXME: docu
*/
int AddButton(int pos, int level, const std::string &icon_ident,
ButtonCmd action, const std::string &value, const ButtonCheckFunc func,
ButtonCmd action, const std::string &value, void* actionCb, const ButtonCheckFunc func,
const std::string &allow, const int key, const std::string &hint, const std::string &descr,
const std::string &sound, const std::string &cursor, const std::string &umask,
const std::string &popup, bool alwaysShow)
@ -116,6 +116,7 @@ int AddButton(int pos, int level, const std::string &icon_ident,
ba->Level = level;
ba->AlwaysShow = alwaysShow;
ba->Icon.Name = icon_ident;
ba->Payload = actionCb;
// FIXME: check if already initited
//ba->Icon.Load();
ba->Action = action;
@ -876,6 +877,7 @@ bool IsButtonAllowed(const CUnit &unit, const ButtonAction &buttonaction)
case ButtonStandGround:
case ButtonButton:
case ButtonMove:
case ButtonCallbackAction:
res = true;
break;
case ButtonRepair:
@ -1335,6 +1337,14 @@ void CButtonPanel::DoClicked_Research(int button)
}
}
void CButtonPanel::DoClicked_CallbackAction(int button)
{
LuaCallback* callback = (LuaCallback*)(CurrentButtons[button].Payload);
callback->pushPreamble();
callback->pushInteger(UnitNumber(*Selected[0]));
callback->run();
}
/**
** Handle bottom button clicked.
**
@ -1384,6 +1394,7 @@ void CButtonPanel::DoClicked(int button)
case ButtonTrain: { DoClicked_Train(button); break; }
case ButtonUpgradeTo: { DoClicked_UpgradeTo(button); break; }
case ButtonResearch: { DoClicked_Research(button); break; }
case ButtonCallbackAction: { DoClicked_CallbackAction(button); break; }
}
}

View file

@ -971,23 +971,30 @@ static int CclDefineButton(lua_State *l)
ba.Action = ButtonCancelTrain;
} else if (!strcmp(value, "cancel-build")) {
ba.Action = ButtonCancelBuild;
} else if (!strcmp(value, "callback")) {
ba.Action = ButtonCallbackAction;
} else {
LuaError(l, "Unsupported button action: %s" _C_ value);
}
} else if (!strcmp(value, "Value")) {
if (!lua_isnumber(l, -1) && !lua_isstring(l, -1)) {
if (!lua_isnumber(l, -1) && !lua_isstring(l, -1) && !lua_isfunction(l, -1)) {
LuaError(l, "incorrect argument");
}
char buf[64];
const char *s2;
if (lua_isnumber(l, -1)) {
snprintf(buf, sizeof(buf), "%ld", (long int)lua_tonumber(l, -1));
s2 = buf;
if (lua_isfunction(l, -1)) {
ba.Payload = new LuaCallback(l, -1);
} else {
s2 = lua_tostring(l, -1);
char buf[64];
const char *s2;
if (lua_isnumber(l, -1)) {
snprintf(buf, sizeof(buf), "%ld", (long int)lua_tonumber(l, -1));
s2 = buf;
} else {
s2 = lua_tostring(l, -1);
}
ba.ValueStr = s2;
}
ba.ValueStr = s2;
} else if (!strcmp(value, "Allowed")) {
value = LuaToString(l, -1);
if (!strcmp(value, "check-true")) {
@ -1072,7 +1079,7 @@ static int CclDefineButton(lua_State *l)
}
lua_pop(l, 1);
}
AddButton(ba.Pos, ba.Level, ba.Icon.Name, ba.Action, ba.ValueStr,
AddButton(ba.Pos, ba.Level, ba.Icon.Name, ba.Action, ba.ValueStr, ba.Payload,
ba.Allowed, ba.AllowStr, ba.Key, ba.Hint, ba.Description, ba.CommentSound.Name,
ba.ButtonCursor, ba.UnitMask, ba.Popup, ba.AlwaysShow);
return 0;