mirror of https://github.com/ArduPilot/ardupilot
Change the way pre-prompt printing works to avoid having to deal with "magic" menu entries.
Add a default 'exit' command to back out of a menu. git-svn-id: https://arducopter.googlecode.com/svn/trunk@546 f9c3cf11-9bcb-44bc-f272-b75c42450872
This commit is contained in:
parent
064dda10bf
commit
e2184615d9
|
@ -20,6 +20,11 @@ public:
|
||||||
/// menu command function
|
/// menu command function
|
||||||
///
|
///
|
||||||
typedef int (*func)(uint8_t argc, const struct arg *argv);
|
typedef int (*func)(uint8_t argc, const struct arg *argv);
|
||||||
|
|
||||||
|
/// menu pre-prompt function
|
||||||
|
///
|
||||||
|
/// If this function returns false, the menu exits.
|
||||||
|
typedef bool (*preprompt)(void);
|
||||||
|
|
||||||
/// menu command description
|
/// menu command description
|
||||||
///
|
///
|
||||||
|
@ -28,8 +33,6 @@ public:
|
||||||
struct command {
|
struct command {
|
||||||
/// Name of the command, as typed or received.
|
/// Name of the command, as typed or received.
|
||||||
/// Command names are limited in size to keep this structure compact.
|
/// Command names are limited in size to keep this structure compact.
|
||||||
/// If the first command in the menu is named '*', it will be called
|
|
||||||
/// each time before printing the prompt.
|
|
||||||
const char command[MENU_COMMAND_MAX];
|
const char command[MENU_COMMAND_MAX];
|
||||||
|
|
||||||
/// The function to call when the command is received.
|
/// The function to call when the command is received.
|
||||||
|
@ -37,6 +40,8 @@ public:
|
||||||
/// MENU_ARGS_MAX. The argv array will be populated with
|
/// MENU_ARGS_MAX. The argv array will be populated with
|
||||||
/// arguments typed/received up to MENU_ARGS_MAX. The command
|
/// arguments typed/received up to MENU_ARGS_MAX. The command
|
||||||
/// name will always be in argv[0].
|
/// name will always be in argv[0].
|
||||||
|
/// Commands may return -2 to cause the menu itself to exit.
|
||||||
|
/// The "?", "help" and "exit" commands are always defined.
|
||||||
int (*func)(uint8_t argc, const struct arg *argv); ///< callback function
|
int (*func)(uint8_t argc, const struct arg *argv); ///< callback function
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -46,7 +51,7 @@ public:
|
||||||
/// @param commands An array of ::command structures.
|
/// @param commands An array of ::command structures.
|
||||||
/// @param entries The number of entries in the menu.
|
/// @param entries The number of entries in the menu.
|
||||||
///
|
///
|
||||||
Menu(const char *prompt, const struct command *commands, uint8_t entries);
|
Menu(const char *prompt, const struct command *commands, uint8_t entries, preprompt ppfunc = 0);
|
||||||
|
|
||||||
/// menu runner
|
/// menu runner
|
||||||
void run(void);
|
void run(void);
|
||||||
|
@ -62,19 +67,27 @@ private:
|
||||||
/// @param argc Number of arguments prepared for the menu item
|
/// @param argc Number of arguments prepared for the menu item
|
||||||
///
|
///
|
||||||
int _call(uint8_t n, uint8_t argc);
|
int _call(uint8_t n, uint8_t argc);
|
||||||
|
|
||||||
const char *_prompt; ///< prompt to display
|
const char *_prompt; ///< prompt to display
|
||||||
const command *_commands; ///< array of commands
|
const command *_commands; ///< array of commands
|
||||||
const uint8_t _entries; ///< size of the menu
|
const uint8_t _entries; ///< size of the menu
|
||||||
|
const preprompt _ppfunc; ///< optional pre-prompt action
|
||||||
|
|
||||||
static char _inbuf[MENU_COMMANDLINE_MAX]; ///< input buffer
|
static char _inbuf[MENU_COMMANDLINE_MAX]; ///< input buffer
|
||||||
static arg _argv[MENU_ARGS_MAX + 1]; ///< arguments
|
static arg _argv[MENU_ARGS_MAX + 1]; ///< arguments
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Macro used to define a menu.
|
/// Macros used to define a menu.
|
||||||
///
|
///
|
||||||
/// Use name.run() to run the menu.
|
/// Use name.run() to run the menu.
|
||||||
///
|
///
|
||||||
|
/// The MENU2 macro supports the optional pre-prompt printing function.
|
||||||
|
///
|
||||||
#define MENU(name, prompt, commands) \
|
#define MENU(name, prompt, commands) \
|
||||||
static const char __menu_name__ ##name[] PROGMEM = prompt; \
|
static const char __menu_name__ ##name[] PROGMEM = prompt; \
|
||||||
static Menu name(__menu_name__ ##name, commands, sizeof(commands) / sizeof(commands[0]))
|
static Menu name(__menu_name__ ##name, commands, sizeof(commands) / sizeof(commands[0]))
|
||||||
|
|
||||||
|
#define MENU2(name, prompt, commands, preprompt) \
|
||||||
|
static const char __menu_name__ ##name[] PROGMEM = prompt; \
|
||||||
|
static Menu name(__menu_name__ ##name, commands, sizeof(commands) / sizeof(commands[0]), preprompt)
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,11 @@ char Menu::_inbuf[MENU_COMMANDLINE_MAX];
|
||||||
Menu::arg Menu::_argv[MENU_ARGS_MAX + 1];
|
Menu::arg Menu::_argv[MENU_ARGS_MAX + 1];
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
Menu::Menu(const prog_char *prompt, const Menu::command *commands, uint8_t entries) :
|
Menu::Menu(const prog_char *prompt, const Menu::command *commands, uint8_t entries, preprompt ppfunc) :
|
||||||
_prompt(prompt),
|
_prompt(prompt),
|
||||||
_commands(commands),
|
_commands(commands),
|
||||||
_entries(entries)
|
_entries(entries),
|
||||||
|
_ppfunc(ppfunc)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,12 +36,10 @@ Menu::run(void)
|
||||||
// loop performing commands
|
// loop performing commands
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
// if the first command is called '*', call it before displaying the menu
|
// run the pre-prompt function, if one is defined
|
||||||
if ("*", _commands[0].command) {
|
if ((NULL != _ppfunc) && !_ppfunc())
|
||||||
if (-2 == _call(0, 0))
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// loop reading characters from the input
|
// loop reading characters from the input
|
||||||
len = 0;
|
len = 0;
|
||||||
Serial.printf("%S] ", _prompt);
|
Serial.printf("%S] ", _prompt);
|
||||||
|
@ -91,12 +90,18 @@ Menu::run(void)
|
||||||
ret = _call(i, argc);
|
ret = _call(i, argc);
|
||||||
if (-2 == ret)
|
if (-2 == ret)
|
||||||
return;
|
return;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the menu doesn't provide more comprehensive help, print the command list
|
// implicit commands
|
||||||
if ((i == _entries) && (!strcmp(_argv[0].str, "?") || (!strcmp_P(_argv[0].str, PSTR("help")))))
|
if (i == _entries) {
|
||||||
_help();
|
if (!strcmp(_argv[0].str, "?") || (!strcmp_P(_argv[0].str, PSTR("help")))) {
|
||||||
|
_help();
|
||||||
|
} else if (!strcmp_P(_argv[0].str, PSTR("exit"))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue