pflib v3.9.0-rc3-11-g2537d8f
Pretty Fine HGCROC Interaction Library
Loading...
Searching...
No Matches
pflib::menu::Menu< T > Class Template Reference

A menu to execute commands with a specific target. More...

#include <Menu.h>

Inheritance diagram for pflib::menu::Menu< T >:
[legend]
Collaboration diagram for pflib::menu::Menu< T >:
[legend]

Classes

class  Line
 A command in the menu. More...
 

Public Types

using TargetHandle = T
 the type of target this menu will hold and pass around
 
using SingleTargetCommand = std::function<void(TargetHandle)>
 type of function which does something with the target
 
using MultipleTargetCommands
 type of function which does one of several commands with target
 
using RenderFuncType = std::function<void(TargetHandle)>
 The type of function used to "render" a menu.
 

Public Member Functions

Menuline (const char *name, const char *desc, SingleTargetCommand ex, unsigned int category=0)
 declare a single target command with thei nput name and desc
 
Menuline (const char *name, const char *desc, MultipleTargetCommands ex, unsigned int category=0)
 declare a single target command with the input name and desc
 
std::shared_ptr< Menusubmenu (const char *name, const char *desc, RenderFuncType f=0, unsigned int category=0)
 declare a sub menu of us with input name and desc
 
void build ()
 Go through and build each of the lines in this menu.
 
 Menu (const Menu &)=delete
 no copying
 
void operator= (const Menu &)=delete
 no copying
 
 Menu (RenderFuncType f=0, unsigned int hidden_categories=0)
 Construct a menu with a rendering function.
 
void hide (unsigned int categories)
 set hidden categories
 
void print (std::ostream &s, int indent=0) const
 Print menu without running it.
 
void render (TargetHandle tgt) const
 render this menu to the user
 
void enter (TargetHandle tgt) const
 entered this menu
 
void steer (TargetHandle p_target) const
 give control over the target to this menu
 

Static Public Member Functions

static Menuroot ()
 Retreve a pointer to the root menu.
 
static void run (TargetHandle tgt)
 Call this function when ready to run.
 
static std::shared_ptr< Menumenu (const char *name, const char *desc, RenderFuncType render_func=0, unsigned int category=0)
 Construct a new menu with the root as parent and optional rendering.
 
- Static Public Member Functions inherited from pflib::menu::BaseMenu
static void set_history_filepath (std::string fp)
 Decide where the filepath for reading/writing the history should be.
 
static void open_history ()
 open history and read from file (if it exists)
 
static void close_history ()
 close up history
 
static std::string readline (const std::string &prompt, const std::string &defval, bool preserve_last_blank=false)
 Read in a parameter using the default value if nothing provided.
 
static std::string readline_nosplit (const std::string &prompt, const std::string &defval)
 Get a raw input value without the additional splitting and modifications done in base readline.
 
static std::string readline (const std::string &prompt)
 Read a string parameter without a default.
 
static std::string readline (const std::string &prompt, const std::vector< std::string > &opts, const std::string &def="")
 Read a string parameter without a default but with the input list of options for tab-completion.
 
static std::string default_path (const std::string &name, const std::string &extension="")
 Create a default path from the output directory and timestamp format parameters.
 
static std::string readline_path (const std::string &name, const std::string &extension="")
 Read a path from the user using default_path to generate a default value.
 
static int readline_int (const std::string &prompt)
 Read an integer parameter without a default.
 
static int readline_int (const std::string &prompt, int aval, bool ashex=false)
 Read an integer parameter with a default.
 
static double readline_float (const std::string &prompt)
 Read a float parameter with a default.
 
static bool readline_bool (const std::string &prompt, bool aval)
 Read a bool parameter with a default.
 
static std::string readline_cmd ()
 Read a command from the menu.
 
static void add_to_command_queue (const std::string &str)
 Add to the queue of commands to execute automatically.
 

Private Member Functions

virtual std::vector< std::stringcommand_options () const
 Provide the list of command options.
 

Private Attributes

std::vector< Linelines_
 lines in this menu
 
RenderFuncType render_func_
 function pointer to render the menu prompt
 
unsigned int hidden_categories_
 bit-wise OR of any category integers that should not be displayed
 

Additional Inherited Members

- Static Public Attributes inherited from pflib::menu::BaseMenu
static std::string output_directory = ""
 output directory to include in default path
 
static std::string timestamp_format = "_%Y%m%d_%H%M%S"
 format of timestamp to append to default path
 
- Protected Member Functions inherited from pflib::menu::BaseMenu
void add_to_history (const std::string &cmd) const
 Add a command to the history of commands that have been executed.
 
- Static Protected Attributes inherited from pflib::menu::BaseMenu
static std::list< std::stringcmdTextQueue_
 the ordered list of commands to be executed from a script file
 
static std::vector< std::stringcmd_options_
 the current command options (for interfacing with readline's tab completion)
 
static const std::vector< std::string > * rl_comp_opts_
 a pointer to the list of options when attempting readline completion
 
::pflib::logging::logger the_log_ = ::pflib::logging::get("menu")
 

Detailed Description

template<typename T>
class pflib::menu::Menu< T >

A menu to execute commands with a specific target.

Generally, it is a good idea to have a header defining the type of menu you wish to operate for your program. In it, you would have a line like

A menu to execute commands with a specific target.
Definition Menu.h:276
The type of menu we are constructing.
Definition pftool.h:45

so that in the files where you are implementing menu commands the registration is less likely to be messed up.

// example registration using above alias
namespace {
auto sb = pftool::menu("SB","example empty submenu");
}
static std::shared_ptr< Menu > menu(const char *name, const char *desc, RenderFuncType render_func=0, unsigned int category=0)
Definition Menu.h:560

and running the menu takes on a more appealing form.

// tgt is a handle to the target of the menu
// i.e. it is of type pftool::TargetHandle
static void run(TargetHandle tgt)
Definition Menu.h:394
Template Parameters
Tclass to be passed to execution commands

Member Typedef Documentation

◆ MultipleTargetCommands

template<typename T >
using pflib::menu::Menu< T >::MultipleTargetCommands
Initial value:
T TargetHandle
the type of target this menu will hold and pass around
Definition Menu.h:279

type of function which does one of several commands with target

◆ RenderFuncType

template<typename T >
using pflib::menu::Menu< T >::RenderFuncType = std::function<void(TargetHandle)>

The type of function used to "render" a menu.

"rendering" allows the user to have a handle for when the menu will be printed to the terminal prompt. Moreover, this can include necessary initiliazation procedures if need be.

Member Function Documentation

◆ build()

template<typename T >
void pflib::menu::Menu< T >::build ( )
inline

Go through and build each of the lines in this menu.

Note
No need to add EXIT/QUIT lines!

Afterwards, we append the "EXIT" line to us.

◆ command_options()

template<typename T >
virtual std::vector< std::string > pflib::menu::Menu< T >::command_options ( ) const
inlineprivatevirtual

Provide the list of command options.

Returns
list of commands that could be run from this menu

◆ enter()

template<typename T >
void pflib::menu::Menu< T >::enter ( TargetHandle tgt) const
inline

entered this menu

There are a few tasks we do when entering this menu:

  1. copy our command_options into the static command options for tab completion
  2. call the user-provided render function
  3. printout the list of commands in this menu
See also
Menu::render for how the last two are done.

These tasks are only done if the command queue is empty signalling that we are not in a script.

◆ line() [1/2]

template<typename T >
Menu * pflib::menu::Menu< T >::line ( const char * name,
const char * desc,
MultipleTargetCommands ex,
unsigned int category = 0 )
inline

declare a single target command with the input name and desc

MultipleTargetCommands functions have a string parameter which is given name when run.

appends this menu line to us and then returns a pointer to us

Parameters
[in]nameName of this line to use when running
[in]descshort description to print with menu
[in]exfunction to execute when name is called
[in]categoryinteger flag categorizing this menu line
Returns
pointer to us

◆ line() [2/2]

template<typename T >
Menu * pflib::menu::Menu< T >::line ( const char * name,
const char * desc,
SingleTargetCommand ex,
unsigned int category = 0 )
inline

declare a single target command with thei nput name and desc

appends this menu line to us and then returns a pointer to us

Parameters
[in]nameName of this line to use when running
[in]descshort description to print with menu
[in]exfunction to execute when name is called
[in]categoryinteger flag categorizing this menu line
Returns
pointer to us

◆ menu()

template<typename T >
static std::shared_ptr< Menu > pflib::menu::Menu< T >::menu ( const char * name,
const char * desc,
RenderFuncType render_func = 0,
unsigned int category = 0 )
inlinestatic

Construct a new menu with the root as parent and optional rendering.

After using submenu to attach ourselves to the input parent, we return a pointer to the newly constructed menu. This is to allow chaining during the declaration of a menu, so that the declaration of a menu has a form similar to what the menu looks like at run time.

A simple example (actually using the shorter alias) is below. one_func and two_func are both functions accessible by this piece of code (either via a header or in this translation unit) and are void functions with take a handle to the target type. color_func is similarly accessible but it takes a string and the target handle. The string will be the command that is selected at runtime (e.g. "RED" if it is typed by the user)

namespace {
auto sb = Menu<T>::menu("SB","example submenu")
->line("ONE", "one command in this menu", one_func)
->line("TWO", "two command in this menu", two_func)
->line("RED", "can have multiple lines directed to the same func",
color_func)
->line("BLUE", "see?" , color_func)
;
}

The anonymous namespace is used to force the variable within it to be static and therefore created at library linking time. The dummy variable is (unfortunately) necessary so that the sub menu can maintain existence throughout the runtime of the program.

See also
submenu for attaching to another menu directly
Parameters
[in]nameName of this sub menu for selection
[in]descdescription of this sub menu
[in]render_funcfunction to use to render this sub menu
[in]categorycategory bit flag for hiding
Returns
pointer to newly created menu

◆ render()

template<typename T >
void pflib::menu::Menu< T >::render ( TargetHandle tgt) const
inline

render this menu to the user

This is its own function because it is called when we enter a menu and if the user wants to print the HELP command

  1. call the user-provided render function
  2. printout the list of commands in this menu

◆ run()

template<typename T >
static void pflib::menu::Menu< T >::run ( TargetHandle tgt)
inlinestatic

Call this function when ready to run.

Provide a TargetHandle to run over.

After rendering the menu, we give tgt to steer to start off.

Parameters
[in]tgtTargetHandle to run with

◆ steer()

template<typename T >
void pflib::menu::Menu< T >::steer ( TargetHandle p_target) const
inline

give control over the target to this menu

We enter a do-while loop that continues until the user selects an empty line to execute. The contents of the do-while loop follow the procedure below.

  1. If we have a render function set, we give the target to it.
  2. If we aren't in batch mode, we print all of our lines and their descriptions.
  3. Use the readline function to get the requested command from the user
    • We use the BaseMenu::command_matcher function to provide options given the user attempting <TAB> completion.
  4. Loop through our lines to find all available matches.
  5. Execute the line if there is a unique match; otherwise, print an error message.
Parameters
[in]p_targetpointer to the target

◆ submenu()

template<typename T >
std::shared_ptr< Menu > pflib::menu::Menu< T >::submenu ( const char * name,
const char * desc,
RenderFuncType f = 0,
unsigned int category = 0 )
inline

declare a sub menu of us with input name and desc

appends this menu line to us and then returns a pointer to us

This can be used if you already have a menu and you wish to add another submenu to it.

namespace {
auto mymain = Menu<T>::menu("MAIN","will be on the root menu");
auto sb = mymain->submenu("SB","A line in the MAIN menu");
}
Parameters
[in]nameName of this line to use when running
[in]descshort description to print with menu
[in]expointer to menu that we should append
[in]categoryinteger flag categorizing this menu line
Returns
pointer to the newly created submenu

The documentation for this class was generated from the following file: