Commit 60da9ca8 authored by alex@thinkpad's avatar alex@thinkpad
Browse files

Lua: more doc updates (WIP)

--HG--
branch : lua_fix
parent 9971e6571d4a
......@@ -3,6 +3,7 @@ file = { '../lua', '../../scripts/lib'}
title = 'ML Lua API'
format = 'markdown'
description = 'Magic Lantern Lua API Documentation'
no_space_before_args = true
full_description = [[
Startup
-------
......@@ -118,4 +119,4 @@ examples = { '../../scripts' }
examples[1]..'/legacy/keys.c',
examples[1]..'/legacy/sokoban.c',
examples[1]..'/legacy/test.c'
}
\ No newline at end of file
}
......@@ -128,7 +128,7 @@ char * copy_string(const char * str)
/***
Event Handlers.
Scripts can repsond to events by setting the functions in the 'event' table.
Scripts can respond to events by setting the functions in the 'event' table.
Event handler functions can take one integer parameter, and must return a boolean
that specifies whether or not the backend should continue executing event handlers
for this particular event.
......
/***
Battery properties
Battery properties.
Only available on cameras that report battery percentage in Canon menu.
These cameras have CONFIG\_BATTERY\_INFO enabled on the [feature comparison matrix](http://builds.magiclantern.fm/features.html).
@author Magic Lantern Team
@copyright 2014
......
......@@ -407,8 +407,8 @@ static int luaCB_aperture_index(lua_State * L)
/// Get/Set aperture as f-number (floating point).
// @tfield number value
else if(!strcmp(key,"value")) lua_pushnumber(L, lens_info.aperture / 10.0);
/// Get/Set minimum (wide open) aperture value (aperture object).
// @tfield aperture min
/// Get minimum (wide open) aperture value (aperture object).
// @tfield aperture min readonly
else if(!strcmp(key,"min"))
{
lua_newtable(L);
......@@ -423,8 +423,8 @@ static int luaCB_aperture_index(lua_State * L)
lua_setfield(L, -2, "fields");
lua_setmetatable(L, -2);
}
/// Get/Set maximum (closed) aperture value (aperture object).
// @tfield aperture max
/// Get maximum (closed) aperture value (aperture object).
// @tfield aperture max readonly
else if(!strcmp(key,"max"))
{
lua_newtable(L);
......
/***
DryOS functions
DryOS operating system functions.
TODO: what about Penlight-like API for file I/O (see e.g.
[pl.path](http://stevedonovan.github.io/Penlight/api/libraries/pl.path.html),
[pl.dir](http://stevedonovan.github.io/Penlight/api/libraries/pl.dir.html),
[pl.file](http://stevedonovan.github.io/Penlight/api/libraries/pl.file.html),
[pl.utils](http://stevedonovan.github.io/Penlight/api/libraries/pl.utils.html))?
Or maybe even porting a subset of [Penlight](http://stevedonovan.github.io/Penlight/api/manual/01-introduction.md.html)
and/or [LFS](https://keplerproject.github.io/luafilesystem/manual.html)?
@author Magic Lantern Team
@copyright 2014
......@@ -20,50 +29,6 @@ static int luaCB_card_newindex(lua_State * L);
static int luaCB_directory_index(lua_State * L);
static int luaCB_directory_newindex(lua_State * L);
/***
Calls an eventproc (a function from the camera firmware which can be called by name).
See Eventprocs. Dangerous - you need to compile Lua yourself in order to enable it.
@tparam string function the name of the function to call
@param[opt] arg argument to pass to the call
@function call
*/
static int luaCB_dryos_call(lua_State * L)
{
#if 1
return luaL_error(L,
"dryos.call() is disabled for safety reasons.\n"
"If you know what you are doing, just remove this message and recompile.\n"
);
#endif
LUA_PARAM_STRING(function_name, 1);
int result = 0;
int argc = lua_gettop(L);
if(argc <= 1)
{
result = call(function_name);
}
else if(lua_isinteger(L, 2))
{
int arg = lua_tointeger(L, 2);
result = call(function_name, arg);
}
else if(lua_isnumber(L, 2))
{
float arg = lua_tonumber(L, 2);
result = call(function_name, arg);
}
else if(lua_isstring(L, 2))
{
const char * arg = lua_tostring(L, 2);
result = call(function_name, arg);
}
lua_pushinteger(L, result);
return 1;
}
const char * lua_dryos_directory_fields[] =
{
"exists",
......@@ -90,7 +55,7 @@ const char * lua_dryos_card_fields[] =
This function does not actually create a directory on the file system, it just creates
an object that represents a directory. To actually create the directory in the file system
call directory:create()
call `directory:create()`.
@usage
local mydir = dryos.directory("mydir")
if mydir.exists == false then
......@@ -167,6 +132,52 @@ static int luaCB_dryos_rename(lua_State * L)
return 1;
}
/***
Calls an eventproc (a function from the camera firmware which can be called by name).
See [Eventprocs](http://magiclantern.wikia.com/wiki/Call_by_name).
Dangerous - you need to compile Lua yourself in order to enable it.
@tparam string function the name of the function to call
@param[opt] arg argument to pass to the call
@function call
*/
static int luaCB_dryos_call(lua_State * L)
{
#if 1
return luaL_error(L,
"dryos.call() is disabled for safety reasons.\n"
"If you know what you are doing, just remove this message and recompile.\n"
);
#endif
LUA_PARAM_STRING(function_name, 1);
int result = 0;
int argc = lua_gettop(L);
if(argc <= 1)
{
result = call(function_name);
}
else if(lua_isinteger(L, 2))
{
int arg = lua_tointeger(L, 2);
result = call(function_name, arg);
}
else if(lua_isnumber(L, 2))
{
float arg = lua_tonumber(L, 2);
result = call(function_name, arg);
}
else if(lua_isstring(L, 2))
{
const char * arg = lua_tostring(L, 2);
result = call(function_name, arg);
}
lua_pushinteger(L, result);
return 1;
}
static void setfield (lua_State *L, const char *key, int value) {
lua_pushinteger(L, value);
lua_setfield(L, -2, key);
......@@ -251,7 +262,7 @@ static int luaCB_dryos_index(lua_State * L)
lua_setfield(L, -2, "fields");
lua_setmetatable(L, -2);
}
/// Gets a table representing the current date/time
/// Gets a table representing the current date/time.
// @tfield date date
else if(!strcmp(key, "date"))
{
......@@ -317,7 +328,7 @@ static int luaCB_dryos_newindex(lua_State * L)
// @type directory
/***
Creates a directory
Creates a directory.
@treturn bool whether or not the directory was sucessfully created
@function create
*/
......@@ -331,7 +342,7 @@ static int luaCB_directory_create(lua_State * L)
}
/***
Get a table (of @{directory} objects) containing this directory's child directories
Get a table (of @{directory} objects) containing this directory's child directories.
@treturn {directory,...}
@function children
*/
......@@ -369,7 +380,7 @@ static int luaCB_directory_children(lua_State * L)
}
/***
Get a table (of @{string}s) that are the file names of this directory's files
Get a table (of @{string}s) that are the file names of this directory's files.
@treturn {string,...}
@function files
*/
......@@ -407,14 +418,14 @@ static int luaCB_directory_index(lua_State * L)
{
if(!lua_istable(L, 1)) return luaL_argerror(L, 1, "expected table");
LUA_PARAM_STRING_OPTIONAL(key, 2, "");
/// Get the full path of the directory
/// Get the full path of the directory.
// @tfield string path
if(!strcmp(key, "path")) return lua_rawget(L, 1);
if(lua_getfield(L, 1, "path") != LUA_TSTRING) return luaL_error(L, "invalid directory path");
const char * path = lua_tostring(L, -1);
lua_pop(L, 1);
/// Get whether or not the directory exists
/// Get whether or not the directory exists.
// @tfield bool exists
if(!strcmp(key, "exists")) lua_pushboolean(L, is_dir(path));
else if(!strcmp(key, "create")) lua_pushcfunction(L, luaCB_directory_create);
......@@ -455,7 +466,7 @@ static int luaCB_directory_newindex(lua_State * L)
return luaL_error(L, "'directory' type is readonly");
}
/// Represents a card (storage media)
/// Represents a card (storage media).
// Inherits from @{directory}
// @type card
......@@ -466,22 +477,24 @@ static int luaCB_card_index(lua_State * L)
if(lua_getfield(L, 1, "_card_ptr") == LUA_TLIGHTUSERDATA)
{
struct card_info * card = lua_touserdata(L, -1);
/// Get the cluster size
/// Get the cluster size of the filesystem.
// @tfield int cluster_size
if(!strcmp(key, "cluster_size")) lua_pushinteger(L, card->cluster_size);
/// Get the drive letter
/// Get the drive letter (A or B).
// @tfield string drive_letter
else if(!strcmp(key, "drive_letter")) lua_pushstring(L, card->drive_letter);
/// Get the current Canon file number
/// Get the current Canon file number (e.g. IMG_1234.CR2 -> 1234).
// @tfield int file_number
else if(!strcmp(key, "file_number")) lua_pushinteger(L, card->file_number);
/// Get the current Canon folder number
/// Get the current Canon folder number (e.g. DCIM/101CANON => 101).
// @tfield int folder_number
else if(!strcmp(key, "folder_number")) lua_pushinteger(L, card->folder_number);
/// Get the current free space (in MiB)
/// Get the current free space (in MiB).
///
/// FIXME: does not update after writing files from ML code.
// @tfield int free_space
else if(!strcmp(key, "free_space")) lua_pushinteger(L, get_free_space_32k(card) * 1024 / 32);
/// Get the type of card
/// Get the type of card (SD or CF).
// @tfield string type
else if(!strcmp(key, "type")) lua_pushstring(L, card->type);
else return luaCB_directory_index(L);
......
......@@ -55,7 +55,13 @@ static int luaCB_beep(lua_State * L)
/***
Pauses for ms miliseconds and allows other tasks to run.
@tparam int amount number of milliseconds to sleep
This will block other tasks/events from this script, but will allow
other scripts, ML tasks or Canon tasks.
TODO: make it identical to task.yield?
@tparam int amount number of milliseconds to sleep.
@function msleep
*/
static int luaCB_msleep(lua_State * L)
......
/***
Intervalometer operations and properties
Intervalometer operations and properties.
@author Magic Lantern Team
@copyright 2014
......@@ -16,14 +16,14 @@
static int luaCB_interval_index(lua_State * L)
{
LUA_PARAM_STRING_OPTIONAL(key, 2, "");
/// Get/Set the interval time (in seconds)
/// Get/Set the interval time (in seconds).
// @tfield int time
if(!strcmp(key, "time")) lua_pushinteger(L, get_interval_time());
/// Get the current number of pictures that have been taken
// @tfield int count
/// Get the current number of pictures that have been taken.
// @tfield int count readonly
else if(!strcmp(key, "count")) lua_pushinteger(L, get_interval_count());
/// Get whether or not the intervalometer is currently running
// @tfield bool running
/// Get whether or not the intervalometer is currently running.
// @tfield bool running readonly
else if(!strcmp(key, "running")) lua_pushboolean(L, is_intervalometer_running());
else lua_rawget(L, 1);
return 1;
......
......@@ -17,7 +17,7 @@ int module_send_keypress(int module_key);
/***
Send a keypress.
@tparam int key the key to press
@tparam constants.KEY key the key to press.
@function press
*/
static int luaCB_key_press(lua_State * L)
......@@ -29,9 +29,9 @@ static int luaCB_key_press(lua_State * L)
/***
Wait for a key to be pressed.
@tparam[opt] int key
@tparam[opt] constants.KEY key
@tparam[opt] int timeout
@treturn int the key that was pressed
@treturn constants.KEY the key that was pressed.
@function wait
*/
static int luaCB_key_wait(lua_State * L)
......
......@@ -17,28 +17,34 @@
static int luaCB_lens_index(lua_State * L)
{
LUA_PARAM_STRING_OPTIONAL(key, 2, "");
/// Get the name of the lens (reported by the lens)
/// Get the name of the lens (reported by the lens).
// @tfield string name readonly
if(!strcmp(key, "name")) lua_pushstring(L, lens_info.name);
/// Get the focal length of the lens (in mm)
/// Get the focal length of the lens (in mm). Only updated in LiveView.
// @tfield int focal_length readonly
else if(!strcmp(key, "focal_length")) lua_pushinteger(L, lens_info.focal_len);
/// Get the current focus distance (in mm)
/// Get the current focus distance (in mm). Only updated in LiveView.
// @tfield int focus_distance readonly
else if(!strcmp(key, "focus_distance")) lua_pushinteger(L, lens_info.focus_dist * 10);
/// Get the hyperfocal distance of the lens (in mm)
/// Get the hyperfocal distance of the lens (in mm). Only updated in LiveView.
///
/// Computed from focal length, focus distance and aperture, see Focus -> DOF Settings menu for options.
// @tfield int hyperfocal readonly
else if(!strcmp(key, "hyperfocal")) lua_pushinteger(L, lens_info.hyperfocal);
/// Get the distance to the DOF near (in mm)
/// Get the distance to the DOF near (in mm). Only updated in LiveView.
///
/// Computed from focal length, focus distance and aperture, see Focus -> DOF Settings menu for options.
// @tfield int dof_near readonly
else if(!strcmp(key, "dof_near")) lua_pushinteger(L, lens_info.dof_near);
/// Get the distance to the DOF far (in mm)
/// Get the distance to the DOF far (in mm). Only updated in LiveView.
///
/// Computed from focal length, focus distance and aperture, see Focus -> DOF Settings menu for options.
// @tfield int dof_far readonly
else if(!strcmp(key, "dof_far")) lua_pushinteger(L, lens_info.dof_far);
/// Get whether or not auto focus is enabled
/// Get whether or not auto focus is enabled.
// @tfield bool af readonly
else if(!strcmp(key, "af")) lua_pushboolean(L, !is_manual_focus());
/// Get the current auto focus mode (may be model-specific)
/// Get the current auto focus mode (may be model-specific, see PROP\_AF\_MODE in property.h).
// @tfield int af_mode readonly
else if(!strcmp(key, "af_mode")) lua_pushinteger(L, af_mode);
else lua_rawget(L, 1);
......@@ -60,7 +66,9 @@ static int luaCB_lens_newindex(lua_State * L)
}
/***
Moves the focus motor a specified number of steps. Only works in LV.
Moves the focus motor a specified number of steps.
Only works in LiveView.
@tparam int num_steps How many steps to move the focus motor (signed).
@tparam[opt=2] int step_size Allowed values: 1, 2 or 3.
@tparam[opt=true] bool wait Wait until each focus command finishes, before queueing others.
......@@ -70,11 +78,13 @@ static int luaCB_lens_newindex(lua_State * L)
Only disable if you know what you are doing.
@tparam[opt=0 if wait else 10ms] int delay Delay between focus commands (ms)
@tparam[opt] int delay Delay between focus commands (ms)
With wait=true, the delay is after each focus command is executed (as reported by Canon firmware).
With wait=true, the delay is after each focus command is finished (as reported by Canon firmware).
With wait=false, the delay is after each focus command is started (without waiting for it to finish).
With wait=false, the delay is after each focus command is sent (without waiting for it to finish).
(_default_ 0 if wait=true, 10ms if wait=false)
@function focus
......@@ -107,8 +117,10 @@ static int wait_focus_status(int timeout, int value)
/***
Performs autofocus, similar to half-shutter press.
Works in both LiveView and in plain photo mode.
@treturn bool whether the operation was successful or not.
@function focus
@function autofocus
*/
static int luaCB_lens_autofocus(lua_State * L)
{
......
......@@ -119,7 +119,7 @@ static int luaCB_lv_stop(lua_State * L)
}
/***
Wait for N LiveView frames in LiveView.
Wait for N frames in LiveView.
@tparam int num_frames
@function wait
*/
......@@ -230,7 +230,7 @@ static int luaCB_lv_info(lua_State * L)
}
/***
Represents an info item that is displayed in the ML info bars in LiveView
Represents an info item that is displayed in the ML info bars in LiveView.
@type lvinfo
*/
......@@ -243,47 +243,51 @@ static int luaCB_lvinfo_index(lua_State * L)
LUA_PARAM_STRING_OPTIONAL(key, 2, "");
/// Function called before displaying; can override strings, dimensions and so on
/// Function called before displaying; can override strings, dimensions and so on.
// @function update
if(!strcmp(key, "update")) lua_rawgeti(L, LUA_REGISTRYINDEX, entry->function_ref);
/// Get/Set the item name (for menu)
/// Get/Set the item name (for menu).
// @tfield string name
else if(!strcmp(key, "name")) lua_pushstring(L, item->name);
/// Get/Set the item value
/// Get/Set the item value.
// @tfield string value
else if(!strcmp(key, "value")) lua_pushstring(L, item->value);
/// Get/Set the item background color
/// Get/Set the item background color.
// @tfield int background see @{constants.COLOR}
else if(!strcmp(key, "background")) lua_pushinteger(L, item->color_bg);
/// Get/Set the item foreground color
/// Get/Set the item foreground color.
// @tfield int foreground see @{constants.COLOR}
else if(!strcmp(key, "foreground")) lua_pushinteger(L, item->color_fg);
/// Get/Set if the item uses custom drawing
/// Get/Set whether the item uses custom drawing.
// @tfield bool custom_drawing
else if(!strcmp(key, "custom_drawing")) lua_pushboolean(L, entry->custom_drawing);
/// Get the item font assigned by the backend
// @tfield int font see @{constants.FONT}
/// Get the item font assigned by the backend.
// @tfield int font readonly see @{constants.FONT}
else if(!strcmp(key, "font")) lua_pushinteger(L, item->fontspec);
/// Get/Set the item height
/// Get/Set the item height.
// @tfield int height
else if(!strcmp(key, "height")) lua_pushinteger(L, item->height);
/// Get/Set the item's preferred position
// @tfield int preferred_position
/// Get/Set the item's preferred horizontal position (signed integer, look up other `struct lvinfo_item` items in ML source code).
// @tfield[opt=0] int preferred_position
else if(!strcmp(key, "preferred_position")) lua_pushinteger(L, item->preferred_position);
/// Get/Set the item priority: if there's not enough space, the items with low priority will disappear
// @tfield int priority
/// Get/Set the item priority: if there's not enough space, the items with low priority will disappear.
// @tfield[opt=0] int priority
else if(!strcmp(key, "priority")) lua_pushinteger(L, item->priority);
/// Get/Set the which bar the item appears on
// @tfield int bar
/// Get/Set the which bar the item appears on (see enum lvinfo_bar in lvinfo.h).
///
/// TODO: constants.
// @tfield[opt=top] int bar
else if(!strcmp(key, "bar")) lua_pushinteger(L, item->which_bar);
/// Get/Set the item width; default: measured from value and fontspec; 0 = do not display this item at all
/// Get/Set the item width; default: measured from value and fontspec.
///
/// 0 = do not display this item at all.
// @tfield int width
else if(!strcmp(key, "width")) lua_pushinteger(L, item->width);
/// Get the item x position
// @tfield int x
/// Get the item x position.
// @tfield int x readonly
else if(!strcmp(key, "x")) lua_pushinteger(L, item->x);
/// Get the item y position
// @tfield int y
/// Get the item y position.
// @tfield int y readonly
else if(!strcmp(key, "y")) lua_pushinteger(L, item->y);
else lua_rawget(L, 1);
return 1;
......
/***
Functions for interacting with the ML menu
Functions for interacting with the ML menu.
@author Magic Lantern Team
@copyright 2014
......@@ -212,31 +212,29 @@ const char * lua_menu_instance_fields[] =
NULL
};
/*** Creates a new menu item
/*** Creates a new menu item.
@tparam table definition
@function new
@return a menu object
@usage
mymenu = menu.new
{
parent = "Scripts",
name = "Lua Test Script",
help = "Some help for this script",
value = 1,
parent = "Movie",
name = "Lua Test Script",
help = "Some help for this script.",
submenu =
{
{
name = "Run",
help = "Run this script.",
icon_type = ICON_TYPE.ACTION,
update = "",
name = "Run",
help = "Run some action.",
update = "",
},
{
name = "Parameter Example",
help = "Help for Parameter Example",
min = 0,
max = 100,
unit = UNIT.DEC,
name = "Parameter Example",
help = "Help for Parameter Example",
min = 0,
max = 100,
unit = UNIT.DEC,
warning = function(this) if this.value == 5 then return "this value is not supported" end end,
},
{
......@@ -294,11 +292,11 @@ static int luaCB_menu_new(lua_State * L)
return 1; //return the userdata object
}
/// Set the value of some existing ML menu entry
// @param menu name of the parent menu ('Audio', 'Expo', 'Overlay', 'Shoot', 'Movie', etc)
// @param entry name of the menu entry
// @param value the value to set
// @return whether or not the call was sucessful
/// Set the value of some existing ML menu entry.
// @tparam string menu name of the parent menu ('Audio', 'Expo', 'Overlay', 'Shoot', 'Movie', etc).
// @tparam string entry name of the menu entry.
// @tparam ?int|string value the value to set.
// @treturn bool whether or not the call was sucessful.
// @function set
static int luaCB_menu_set(lua_State * L)
{
......@@ -319,10 +317,10 @@ static int luaCB_menu_set(lua_State * L)
return 1;
}
/// Get the value of some existing ML menu entry
// @param menu name of the parent menu ('Audio', 'Expo', 'Overlay', 'Shoot', 'Movie', etc)
// @param entry name of the menu entry
// @return the value of the menu entry
/// Get the value of some existing ML menu entry.
// @tparam string menu name of the parent menu ('Audio', 'Expo', 'Overlay', 'Shoot', 'Movie', etc)
// @tparam string entry name of the menu entry
// @treturn int the value of the menu entry (current selection)
// @function get
static int luaCB_menu_get(lua_State * L)
{
......@@ -332,8 +330,8 @@ static int luaCB_menu_get(lua_State * L)
return 1;
}
/// Block the ML menu from redrawing (if you wand to do custom drawing)
// @tparam bool enaabled
/// Block the ML menu from redrawing (if you wand to do custom drawing).
// @tparam bool enabled
// @function block
static int luaCB_menu_block(lua_State * L)
{
......@@ -342,7 +340,9 @@ static int luaCB_menu_block(lua_State * L)
return 0;
}
/// Open ML menu
/// Open ML menu.
///
/// Optionally, it may also select the requested menu.
// @param[opt] menu name of the parent menu ('Audio', 'Expo', 'Overlay', 'Shoot', 'Movie', etc)
// @param[opt] entry name of the menu entry
// @function open
......@@ -361,7 +361,7 @@ static int luaCB_menu_open(lua_State * L)
return 0;
}
/// Close ML menu
/// Close ML menu.
// @function close
static int luaCB_menu_close(lua_State * L)
{
......@@ -373,7 +373,7 @@ static int luaCB_menu_close(lua_State * L)
static int luaCB_menu_index(lua_State * L)
{
LUA_PARAM_STRING_OPTIONAL(key, 2, "");
/// Get whether or not the ML menu is visible
/// Get whether or not the ML menu is visible.
//@tfield bool visible
if(!strcmp(key, "visible")) lua_pushboolean(L, gui_menu_shown());
else lua_rawget(L, 1);
......@@ -388,7 +388,7 @@ static int luaCB_menu_newindex(lua_State * L)
return 0;
}