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 (6277B)


0 # stamen 1 2 Static menu generator written in C++20 3 4 ## Description 5 6 This project allows for a creation of static menus, to be used in C or C++, on 7 the fly. The stamen library acts as a framework for linking and keeping track 8 of the menus, whilst allowing a custom display function to be used for maximum 9 flexibility. In dynamic mode configuration file can be read on the fly without 10 recompilation. 11 12 The main goal of this project is experimentation. I have been toying with menus 13 for a while and I've noticed a lot of boilerplate code emerging. That's why I 14 decided to automate the task by generating menus on the fly. 15 16 The main advantage of stamen is two modes it can operate in: 17 1) Static mode, where the menus are pregenerated and linked together with zero cost. 18 2) Dynamic mode, where menus are generated on the fly (possibly in runtime) without recompilation. 19 20 21 ## Dependencies 22 23 * CMake 3.25.2 or latter 24 * Compiler with C++20 support (tested: clang 16.0.5, gcc 13.2.0) 25 * [Poafloc 1.1](https://github.com/DimitrijeDobrota/poafloc) 26 27 28 ## Building and installing 29 30 See the [BUILDING](BUILDING.md) document. 31 32 33 ## Usage 34 35 > Please reference example folder for relevant usage example. 36 37 > Refer to example/CMakeLists.txt to see how to integrate stamen into build system 38 39 There are a few things needed before you begin. 40 41 * All types and functions with prefixes `stamen_` and `stamen_menu_` are also 42 available in namespaces `stamen::` and `stamen::menu::` in C++ for easier use. 43 * Panel and item codes must be one word. In addition they must be valid C/C++ 44 function names if static menu is to be build correctly. 45 * Each free function must have `int name(int);` signature as prescribed by 46 `stamen_callback_f`. Passed int it is intended to detonate the position of an 47 item in the previous panel which is essential for dynamic menu implementation, 48 but it is not required to be used like that. 49 50 ### Configuration 51 52 In order to generate the desired menu, a configuration file needs to be 53 written. Here is an example: 54 ``` 55 + menu_main Main Menu 56 - submenu_1 Enter Submenu 1 57 - submenu_2 Enter Submenu 2 58 - finish Quit 59 60 + submenu_1 Submenu 1 61 - operation1 Operation 1 62 - operation2 Operation 2 63 64 + submenu_2 Submenu 2 65 - operation1 Operation 1 66 - operation2 Operation 2 67 ``` 68 69 Configuration file consists of 2 types of entities: panels and items. Empty 70 lines are ignored. 71 72 Panel is detonated by `+` sign at the start of the line and consists of two 73 parts: code(one word) and title(rest of the line). 74 75 Item entity is detonated by `-` sign at the start of the line and consists of 76 two parts: code(one word) and prompt(rest of the line). 77 78 Panel entity creates a new panel, and each subsequent menu item is added as an 79 option to the panel, until new panel is created. 80 81 Panel code is an unique reference to the panel, whilst item code can be a 82 reference to another panel or any other function (from now on referred to as 83 `free function`). 84 85 86 ### Static menu 87 88 > Please refer to `stamen --help` for list of all options 89 90 After writing a configuration file, run `stamen <config file>` which 91 will create source file and include file in the current directory with the name 92 as the configuration file but with extensions `.cpp` and `.hpp` respectively. 93 You can create files with extensions `.c` and `.h` by appending adding `--c` 94 flag to the command line arguments. 95 96 Include file will contain declarations for all of the menu functions. You 97 should include this file in your code. 98 99 Source file contains definitions for the menu functions. It also includes 100 `shared.h` file which should contain declarations for all of the free functions 101 you have specified in the configuration. The name of the file with free functions 102 can be changed with `--header NAME` flag; 103 104 Custom display function to be used can be set with `-d FUNC` flag. Specified 105 function will be forward-declared according to `stamen_display_f`, so you 106 don't have to worry about doing it yourself. 107 108 Generated source file should be compiled with the rest of your code. If 109 `stamen_builtin_display` is not used, there is no need to link with the stamen library. 110 111 You can call any function to display the menu starting from that specific pane. 112 113 114 ### Custom display function 115 116 Please refer to the implementation of `stamen_builtin_display` to get a general 117 idea of the direction. 118 119 A display function should have `int name(const char*, const stamen_item_t[], int)` 120 signature as prescribed by `stamen_display_f`. 121 122 After prompting user to select one of the items all you have to do is call a 123 function pointed to by the callback field on selected item to invoke the next 124 panel or free function. The return type of int is intended to be used as a 125 measure how many panels back should be backtracked after a free function 126 terminates, but you can use in any way you see fit. 127 128 129 ### Dynamic menu 130 131 In dynamic mode, configuration file is read every time the program is run. In 132 order to invoke the menu you need to add the following snippet to your C 133 program: 134 135 ``` 136 #include <stamen.h> 137 138 // read the configuration 139 stamen_menu_read("path to config"); 140 141 // register free functions 142 stamen_menu_insert("free function code", some_free_function); 143 ... 144 145 // start the menu on specific panel 146 stamen_menu_dynamic("panel code", display_function); 147 ``` 148 149 For C++ there is a namespaced version of the functions: 150 ``` 151 #include <stamen.h> 152 153 // read the configuration 154 stamen::menu::read("path to config"); 155 156 // register free functions 157 stamen::menu::insert("free function code", some_free_function); 158 ... 159 160 // start the menu on specific panel 161 stamen::menu::dynamic("panel code", display_function); 162 ``` 163 164 For the dynamic mode the work, you program needs to be linked with the stamen 165 library with C++ compiler as the last step, regardless whether the program was 166 written in C or C++. 167 168 169 ## Version History 170 171 - 1.2 172 * Modernize CMake project 173 * Modernize codebase 174 175 - 1.1 176 * Separate C and C++ interfaces 177 * Separate dynamic mode into menu namespace 178 * Improve functionality of code generation 179 * Get rid of unnecessary moving parts (stamen_display, ...) 180 * Clean up implementation 181 182 - 1.0 183 * Initial Release 184 185 186 ## Contributing 187 188 See the [CONTRIBUTING](CONTRIBUTING.md) document. 189 190 191 ## License 192 193 This project is licensed under the MIT License - 194 see the [LICENSE](LICENSE.md) file for details 195 196