]> git.sesse.net Git - vlc/commitdiff
Prefer use of function references for buttons
authorAntoine Cellerier <dionoea@videolan.org>
Tue, 2 Mar 2010 13:51:05 +0000 (14:51 +0100)
committerAntoine Cellerier <dionoea@videolan.org>
Tue, 2 Mar 2010 20:27:05 +0000 (21:27 +0100)
Use of function references rather than function names to store button
actions. This allows using all kinds of functions, including non global
ones. Note that the old mechanism using global function names is not
supported anymore. Existing scripts will need to be fixed (-> just
remove the quotes around the function name).

modules/misc/lua/extension.c
modules/misc/lua/libs/dialog.c
share/lua/README.txt
share/lua/extensions/imdb.lua

index 309b778a0a78e392bd9ab2d664f49f70a14e9c22..51769ca86c51dbb9362c07df4cc452359e4de420 100644 (file)
@@ -593,7 +593,10 @@ int lua_ExtensionWidgetClick( extensions_manager_t *p_mgr,
     if( !p_ext->p_sys->L )
         return VLC_SUCCESS;
 
-    return lua_ExecuteFunction( p_mgr, p_ext, (const char*) p_widget->p_sys, LUA_END );
+    lua_State *L = GetLuaState( p_mgr, p_ext );
+    lua_pushlightuserdata( L, p_widget );
+    lua_gettable( L, LUA_REGISTRYINDEX );
+    return lua_ExecuteFunction( p_mgr, p_ext, NULL, LUA_END );
 }
 
 
@@ -796,6 +799,9 @@ int lua_ExecuteFunction( extensions_manager_t *p_mgr, extension_t *p_ext,
 
 /**
  * Execute a function in a Lua script
+ * @param psz_function Name of global function to execute. If NULL, assume
+ *                     that the function object is already on top of the
+ *                     stack.
  * @return < 0 in case of failure, >= 0 in case of success
  * @note It's better to call this function from a dedicated thread
  * (see extension_thread.c)
@@ -809,7 +815,8 @@ int lua_ExecuteFunctionVa( extensions_manager_t *p_mgr, extension_t *p_ext,
     assert( p_ext != NULL );
 
     lua_State *L = GetLuaState( p_mgr, p_ext );
-    lua_getglobal( L, psz_function );
+    if( psz_function )
+        lua_getglobal( L, psz_function );
 
     if( !lua_isfunction( L, -1 ) )
     {
index 0cddd3072defb867f21acbaac8400372001a5f9f..ebb1a3e8d9bcffcf94f8382f4e351c4fc592f7b7 100644 (file)
@@ -388,13 +388,17 @@ int lua_DialogFlush( lua_State *L )
 static int vlclua_dialog_add_button( lua_State *L )
 {
     /* Verify arguments */
-    if( !lua_isstring( L, 2 ) || !lua_isstring( L, 3 ) )
+    if( !lua_isstring( L, 2 ) || !lua_isfunction( L, 3 ) )
         return luaL_error( L, "dialog:add_button usage: (text, func)" );
 
     extension_widget_t *p_widget = calloc( 1, sizeof( extension_widget_t ) );
     p_widget->type = EXTENSION_WIDGET_BUTTON;
     p_widget->psz_text = strdup( luaL_checkstring( L, 2 ) );
-    p_widget->p_sys = strdup( luaL_checkstring( L, 3 ) );
+    lua_settop( L, 3 );
+    lua_pushlightuserdata( L, p_widget );
+    lua_insert( L, 3 );
+    lua_settable( L, LUA_REGISTRYINDEX );
+    p_widget->p_sys = NULL;
 
     return vlclua_create_widget_inner( L, 2, p_widget );
 }
@@ -878,6 +882,13 @@ static int vlclua_dialog_delete_widget( lua_State *L )
 
     /* Delete widget */
     *pp_widget = NULL;
+    if( p_widget->type == EXTENSION_WIDGET_BUTTON )
+    {
+        /* Remove button action from registry */
+        lua_pushlightuserdata( L, p_widget );
+        lua_pushnil( L );
+        lua_settable( L, LUA_REGISTRYINDEX );
+    }
 
     vlc_object_t *p_mgr = vlclua_get_this( L );
 
index dec466fe63ae902441be743559a44b97c4b956da..aebf0b15b08d25bfc5bc2d79e3142f7c69450b4b 100644 (file)
@@ -63,7 +63,7 @@ They define the position of a widget in the dialog:
 - row_span, col_span represent the relative size of a widget on the grid. A widget with col_span = 4 will be displayed as wide as 4 widgets of col_span = 1.
 Example: w = d:add_label( "My Label", 2, 3, 4, 5 ) will create a label at row 3, col 2, with a relative width of 4, height of 5.
 
-d:add_button( text, func, ... ): Create a button with caption "text" (string). When clicked, call function "func". func is a string.
+d:add_button( text, func, ... ): Create a button with caption "text" (string). When clicked, call function "func". func is a function reference.
 d:add_label( text, ... ): Create a text label with caption "text" (string).
 d:add_html( text, ... ): Create a rich text label with caption "text" (string), that supports basic HTML formatting (such as <i> or <h1> for instance).
 d:add_text_input( text, ... ): Create an editable text field, in order to read user input.
index 6509d562ee4130876bcc51b295b6f5a0a0ae677d..93b0cd9019dc939a5fc2f13a737ad91f21db75f7 100644 (file)
@@ -57,8 +57,8 @@ function create_dialog()
     dlg:add_label("<b>Movie Title</b>", 1, 2, 1, 1)
     local item = vlc.input.item()
     txt = dlg:add_text_input(item and item:name() or "", 2, 2, 1, 1)
-    dlg:add_button("Okay", "click_okay", 3, 2, 1, 1)
-    dlg:add_button("*", "update_title", 4, 2, 1, 1)
+    dlg:add_button("Okay", click_okay, 3, 2, 1, 1)
+    dlg:add_button("*", update_title, 4, 2, 1, 1)
     dlg:show() -- Show, if not already visible
 end
 
@@ -91,7 +91,7 @@ function click_okay()
 
     if not list then
         list = dlg:add_list(1, 3, 4, 1)
-        button_open = dlg:add_button("Open", "click_open", 1, 4, 4, 1)
+        button_open = dlg:add_button("Open", click_open, 1, 4, 4, 1)
     end
 
     -- Clear previous results