stamen

Static Menu Generator
git clone git://git.dimitrijedobrota.com/stamen.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

README.md (5314B)


0 # stamen 1 2 Static menu generator written in C++20 3 4 ## Description 5 6 This project is a code generation tool that takes care of the menus. The 7 stamen acts as a framework for linking and keeping track of the menus, whilst 8 allowing a custom display function to be used for maximum flexibility. In 9 dynamic mode configuration file can be read on the fly without recompilation. 10 11 The main goal of this project is experimentation. I have been toying with menus 12 for a while and I've noticed a lot of boilerplate code emerging. That's why I 13 decided to automate the task by generating menus on the fly. 14 15 The main advantage of stamen is two modes it can operate in: 16 1) Static mode, where the menus are pregenerated and linked together with zero cost. 17 2) Dynamic mode, where menus are generated on the fly (possibly in runtime) without recompilation. 18 19 20 ## Dependencies 21 22 * CMake 3.14 or latter 23 * Compiler with C++20 support (tested: clang 19.1.7, gcc 14.2.1) 24 25 26 ## Building and installing 27 28 See the [`BUILDING`](BUILDING.md) document. 29 30 31 ## Usage 32 33 > Please reference example folder for relevant usage examples. 34 35 > Refer to example/CMakeLists.txt to see how to integrate stamen into build system 36 37 There are a few things needed before you begin. 38 39 * Panel and item codes must be one word. In addition they must be valid C++ 40 function names if static menu is to be build correctly. 41 * Each free function must have `int name(std::size_t);` signature as prescribed by 42 `stamen::callback_f`. Passed value is intended to detonate the position of an 43 item in the previous panel which is essential for dynamic menu implementation, 44 but it is not required to be used like that. 45 46 ### Configuration 47 48 In order to generate the desired menu, a configuration file needs to be 49 written. Here is an example: 50 ``` 51 + menu_main Main Menu 52 - submenu_1 Enter Submenu 1 53 - submenu_2 Enter Submenu 2 54 - finish Quit 55 56 + submenu_1 Submenu 1 57 - operation1 Operation 1 58 - operation2 Operation 2 59 60 + submenu_2 Submenu 2 61 - operation1 Operation 1 62 - operation2 Operation 2 63 ``` 64 65 Configuration file consists of 2 types of entities: panels and items. Empty 66 lines are ignored. 67 68 Panel is detonated by `+` sign at the start of the line and consists of two 69 parts: code(one word) and title(rest of the line). 70 71 Item entity is detonated by `-` sign at the start of the line and consists of 72 two parts: code(one word) and prompt(rest of the line). 73 74 Panel entity creates a new panel, and each subsequent menu item is added as an 75 option to the panel, until new panel is created. 76 77 Panel code is an unique reference to the panel, whilst item code can be a 78 reference to another panel or any other function (from now on referred to as 79 `free function`). 80 81 82 ### Static menu 83 84 > Please refer to `stamen --help` for list of all options 85 86 After writing a configuration file, run `stamen <config file>` which 87 will create source file and include file in the current directory with the name 88 as the configuration file but with extensions `.cpp` and `.hpp` respectively. 89 90 Include file will contain declarations for all of the menu functions, as well 91 as the class to be used in this specific menu instance. You should include this 92 file in your code. 93 94 Generated source file should be compiled with the rest of your code, as it 95 contains definitions for the menu functions. 96 97 User should give a definition of `menu_t::visit(const menu_t& menu)`, that 98 actually renders the menu end prompts the user for action. 99 100 You can call any function to display the menu starting from that specific panel. 101 102 103 ### Custom display function 104 105 Please refer to the implementation in `example/static.cpp` to get a general 106 idea of the direction. 107 108 After prompting user to select one of the items all you have to do is call a 109 function pointed to by the callback field on selected item to invoke the next 110 panel or free function. The return type of int is intended to be used as a 111 measure how many panels back should be backtracked after a free function 112 terminates, but you can use in any way you see fit. 113 114 115 ### Dynamic menu 116 117 In dynamic mode, configuration file is read every time the program is run. In 118 order to invoke the menu you need to add the following snippet: 119 120 ``` 121 #include "stamen/stamen.hpp" 122 123 // read the configuration 124 stamen::Stamen inst(ifs); 125 126 // register free functions 127 inst.insert("free function code", some_free_function); 128 ... 129 130 // start the menu on specific panel 131 inst.dynamic("menu_main", display); 132 ... 133 ``` 134 135 For the dynamic mode the work, you program needs to be linked with the stamen 136 library with C++ compiler as the last step. 137 138 139 ## Version History 140 141 - 1.3 142 * Drop C support (it was fun while it lasted) 143 * Use [`Cemplate`](https://github.com/DimitrijeDobrota/cemplate) for code generation 144 * No need to include stamen headers as everything is self contained 145 * Cleanup the code with better implementation 146 147 - 1.2 148 * Modernize CMake project 149 * Modernize codebase 150 151 - 1.1 152 * Separate C and C++ interfaces 153 * Separate dynamic mode into menu namespace 154 * Improve functionality of code generation 155 * Get rid of unnecessary moving parts (stamen_display, ...) 156 * Clean up implementation 157 158 - 1.0 159 * Initial Release 160 161 162 ## Contributing 163 164 See the [`CONTRIBUTING`](CONTRIBUTING.md) document. 165 166 167 ## License 168 169 This project is licensed under the MIT License - see the [`LICENSE`](LICENSE.md) file for details 170 171