summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Wilgus <me.theuser@yahoo.com>2019-09-14 04:35:15 -0500
committerWilliam Wilgus <me.theuser@yahoo.com>2019-09-14 04:48:04 -0500
commit13245ebf76c6911dde283f0be180423c12d9b79c (patch)
tree651fb3db199fdc58825ae7884f26ad5623f81d52
parentf9225da811b7babce7218f71bf4dd954dff0ed6c (diff)
downloadrockbox-13245ebf76c6911dde283f0be180423c12d9b79c.tar.gz
rockbox-13245ebf76c6911dde283f0be180423c12d9b79c.zip
lua add menu callback
forum user fprockboxer asked for a way to detect long presses within the do_menu routine this adds that functionality result = rb.do_menu("Title",t_items, start, menu_callback) function menu_callback(action) ... return action end Change-Id: I110c590095a743a57d0a7d45b24309899a4629cf
-rw-r--r--apps/plugins/lua/rocklib.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/apps/plugins/lua/rocklib.c b/apps/plugins/lua/rocklib.c
index 033975d7fe..77b49dc8ec 100644
--- a/apps/plugins/lua/rocklib.c
+++ b/apps/plugins/lua/rocklib.c
@@ -202,18 +202,60 @@ RB_WRAP(gui_syncyesno_run)
202 return 1; 202 return 1;
203} 203}
204 204
205static lua_State* store_luastate(lua_State *L, bool bStore)
206{
207 /* it is dangerous to store the lua state byond its guaranteed lifetime
208 be sure to clear state asap (as in before you exit the calling function) */
209 static lua_State *LStored = NULL;
210 if(bStore)
211 LStored = L;
212 return LStored;
213}
214
215static int menu_callback(int action, const struct menu_item_ex *this_item)
216{
217 (void) this_item;
218 static int lua_ref = LUA_NOREF;
219 lua_State *L = store_luastate(NULL, false);
220 if(!L)
221 {
222 lua_ref = action;
223 action = ACTION_STD_CANCEL;
224 }
225 else if (lua_ref != LUA_NOREF)
226 {
227 lua_rawgeti(L, LUA_REGISTRYINDEX, lua_ref);
228 lua_pushnumber(L, action);
229 lua_pcall (L, 1, 1, 0);
230 action = luaL_optnumber (L, -1, ACTION_STD_CANCEL);
231 lua_pop(L, 1);
232 }
233
234 return action;
235}
236
205RB_WRAP(do_menu) 237RB_WRAP(do_menu)
206{ 238{
207 struct menu_callback_with_desc menu_desc = {NULL, NULL, Icon_NOICON}; 239 struct menu_callback_with_desc menu_desc = {NULL, NULL, Icon_NOICON};
208 struct menu_item_ex menu = {MT_RETURN_ID | MENU_HAS_DESC, {.strings = NULL}, 240 struct menu_item_ex menu = {MT_RETURN_ID | MENU_HAS_DESC, {.strings = NULL},
209 {.callback_and_desc = &menu_desc}}; 241 {.callback_and_desc = &menu_desc}};
210 int n, start_selected; 242 int n, start_selected;
243 int ref_lua = LUA_NOREF;
211 const char **items, *title; 244 const char **items, *title;
212 245
213 title = luaL_checkstring(L, 1); 246 title = luaL_checkstring(L, 1);
214 247
215 start_selected = lua_tointeger(L, 3); 248 start_selected = lua_tointeger(L, 3);
216 249
250 if (lua_isfunction (L, -1))
251 {
252 /*lua callback function cb(action) return action end */
253 ref_lua = luaL_ref(L, LUA_REGISTRYINDEX);
254 menu_callback(ref_lua, NULL);
255 store_luastate(L, true);
256 menu_desc.menu_callback = &menu_callback;
257 }
258
217 /* newuserdata will be pushed onto stack after args*/ 259 /* newuserdata will be pushed onto stack after args*/
218 items = get_table_items(L, 2, &n); 260 items = get_table_items(L, 2, &n);
219 261
@@ -223,6 +265,13 @@ RB_WRAP(do_menu)
223 265
224 int result = rb->do_menu(&menu, &start_selected, NULL, false); 266 int result = rb->do_menu(&menu, &start_selected, NULL, false);
225 267
268 if (ref_lua != LUA_NOREF)
269 {
270 store_luastate(NULL, true);
271 luaL_unref (L, LUA_REGISTRYINDEX, ref_lua);
272 menu_callback(LUA_NOREF, NULL);
273 }
274
226 lua_pushinteger(L, result); 275 lua_pushinteger(L, result);
227 return 1; 276 return 1;
228} 277}