stamen

Stamen - static menu generator
git clone git://git.dimitrijedobrota.com/stamen.git
Log | Files | Refs | README | LICENSE

README.md (6277B)


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