1 /**
2  * @file
3  * GUI present the user with a selectable list
4  *
5  * @authors
6  * Copyright (C) 2018 Richard Russon <rich@flatcap.org>
7  *
8  * @copyright
9  * This program is free software: you can redistribute it and/or modify it under
10  * the terms of the GNU General Public License as published by the Free Software
11  * Foundation, either version 2 of the License, or (at your option) any later
12  * version.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License along with
20  * this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 /**
24  * @page lib_menu Menu
25  *
26  * A selectable list
27  *
28  * | File             | Description             |
29  * | :--------------- | :---------------------- |
30  * | menu/config.c    | @subpage menu_config    |
31  * | menu/draw.c      | @subpage menu_draw      |
32  * | menu/menu.c      | @subpage menu_menu      |
33  * | menu/move.c      | @subpage menu_move      |
34  * | menu/observer.c  | @subpage menu_observer  |
35  * | menu/window.c    | @subpage menu_window    |
36  */
37 
38 #ifndef MUTT_MENU_LIB_H
39 #define MUTT_MENU_LIB_H
40 
41 #include "config.h"
42 #include <stdbool.h>
43 #include <stdint.h>
44 #include <stdio.h>
45 #include "mutt/lib.h"
46 #include "type.h"
47 
48 struct ConfigSubset;
49 
50 typedef uint8_t MenuRedrawFlags;       ///< Flags, e.g. #MENU_REDRAW_INDEX
51 #define MENU_REDRAW_NO_FLAGS        0  ///< No flags are set
52 #define MENU_REDRAW_INDEX     (1 << 0) ///< Redraw the index
53 #define MENU_REDRAW_MOTION    (1 << 1) ///< Redraw after moving the menu list
54 #define MENU_REDRAW_CURRENT   (1 << 2) ///< Redraw the current line of the menu
55 #define MENU_REDRAW_FULL      (1 << 3) ///< Redraw everything
56 #define MENU_REDRAW_BODY      (1 << 4) ///< Redraw the pager
57 #define MENU_REDRAW_FLOW      (1 << 5) ///< Used by pager to reflow text
58 
59 /**
60  * @defgroup menu_api Menu API
61  *
62  * The Menu API
63  *
64  * GUI selectable list of items
65  */
66 struct Menu
67 {
68   int current;              ///< Current entry
69   int max;                  ///< Number of entries in the menu
70   MenuRedrawFlags redraw;   ///< When to redraw the screen
71   enum MenuType type;       ///< Menu definition for keymap entries
72   int pagelen;              ///< Number of entries per screen
73   bool tagprefix : 1;       ///< User has pressed <tag-prefix>
74   struct MuttWindow *win;   ///< Window holding the Menu
75   struct MuttWindow *win_ibar;
76   struct ConfigSubset *sub; ///< Inherited config items
77 
78   /* Setting a non-empty dialog overrides normal menu behavior.
79    * In dialog mode menubar is hidden and prompt keys are checked before
80    * normal menu movement keys. This can cause problems with scrolling, if
81    * prompt keys override movement keys.  */
82   ARRAY_HEAD(, char *) dialog; ///< Dialog lines themselves
83   char *prompt;                ///< Prompt for user, similar to mutt_multi_choice
84   char *keys;                  ///< Keys used in the prompt
85 
86   /* the following are used only by menu_loop() */
87   int top;                ///< Entry that is the top of the current page
88   int oldcurrent;         ///< For driver use only
89   int search_dir;         ///< Direction of search
90   int tagged;             ///< Number of tagged entries
91   bool custom_search : 1; ///< The menu implements its own non-Menu::search()-compatible search, trickle OP_SEARCH*
92 
93   /**
94    * @defgroup menu_make_entry make_entry()
95    * @ingroup menu_api
96    *
97    * make_entry - Format a item for a menu
98    * @param[in]  menu   Menu containing items
99    * @param[out] buf    Buffer in which to save string
100    * @param[in]  buflen Buffer length
101    * @param[in]  line   Menu line number
102    */
103   void (*make_entry)(struct Menu *menu, char *buf, size_t buflen, int line);
104 
105   /**
106    * @defgroup menu_search search()
107    * @ingroup menu_api
108    *
109    * search - Search a menu for a item matching a regex
110    * @param menu Menu to search
111    * @param rx   Regex to match
112    * @param line Menu entry to match
113    * @retval  0 Success
114    * @retval >0 Error, e.g. REG_NOMATCH
115    */
116   int (*search)(struct Menu *menu, regex_t *rx, int line);
117 
118   /**
119    * @defgroup menu_tag tag()
120    * @ingroup menu_api
121    *
122    * tag - Tag some menu items
123    * @param menu Menu to tag
124    * @param sel  Current selection
125    * @param act  Action: 0 untag, 1 tag, -1 toggle
126    * @retval num Net change in number of tagged attachments
127    */
128   int (*tag)(struct Menu *menu, int sel, int act);
129 
130   /**
131    * @defgroup menu_color color()
132    * @ingroup menu_api
133    *
134    * color - Calculate the colour for a line of the menu
135    * @param menu Menu containing items
136    * @param line Menu line number
137    * @retval >0 Colour pair in an integer
138    * @retval  0 No colour
139    */
140   int (*color)(struct Menu *menu, int line);
141 
142   /**
143    * @defgroup menu_custom_redraw custom_redraw()
144    * @ingroup menu_api
145    *
146    * custom_redraw - Redraw the menu
147    * @param menu Menu to redraw
148    */
149   void (*custom_redraw)(struct Menu *menu);
150 
151   struct Notify *notify;  ///< Notifications
152 
153   void *mdata;            ///< Private data
154 
155   /**
156    * @defgroup menu_mdata_free mdata_free()
157    * @ingroup menu_api
158    *
159    * mdata_free - Free the private data attached to the Menu
160    * @param menu Menu
161    * @param ptr Menu data to free
162    *
163    * **Contract**
164    * - @a menu is not NULL
165    * - @a ptr  is not NULL
166    * - @a *ptr is not NULL
167    */
168   void (*mdata_free)(struct Menu *menu, void **ptr);
169 };
170 
171 // Simple movement
172 MenuRedrawFlags menu_bottom_page   (struct Menu *menu);
173 MenuRedrawFlags menu_current_bottom(struct Menu *menu);
174 MenuRedrawFlags menu_current_middle(struct Menu *menu);
175 MenuRedrawFlags menu_current_top   (struct Menu *menu);
176 MenuRedrawFlags menu_first_entry   (struct Menu *menu);
177 MenuRedrawFlags menu_half_down     (struct Menu *menu);
178 MenuRedrawFlags menu_half_up       (struct Menu *menu);
179 MenuRedrawFlags menu_last_entry    (struct Menu *menu);
180 MenuRedrawFlags menu_middle_page   (struct Menu *menu);
181 MenuRedrawFlags menu_next_entry    (struct Menu *menu);
182 MenuRedrawFlags menu_next_line     (struct Menu *menu);
183 MenuRedrawFlags menu_next_page     (struct Menu *menu);
184 MenuRedrawFlags menu_prev_entry    (struct Menu *menu);
185 MenuRedrawFlags menu_prev_line     (struct Menu *menu);
186 MenuRedrawFlags menu_prev_page     (struct Menu *menu);
187 MenuRedrawFlags menu_top_page      (struct Menu *menu);
188 
189 void         menu_redraw_current(struct Menu *menu);
190 void         menu_redraw_full   (struct Menu *menu);
191 void         menu_redraw_index  (struct Menu *menu);
192 void         menu_redraw_motion (struct Menu *menu);
193 void         menu_redraw_status (struct Menu *menu);
194 int          menu_redraw        (struct Menu *menu);
195 
196 void         menu_add_dialog_row(struct Menu *menu, const char *row);
197 void         menu_cleanup(void);
198 enum MenuType menu_get_current_type(void);
199 void         menu_init(void);
200 int          menu_loop(struct Menu *menu);
201 
202 struct MuttWindow *menu_new_window(enum MenuType type, struct ConfigSubset *sub);
203 
204 int  menu_get_index(struct Menu *menu);
205 MenuRedrawFlags menu_set_index(struct Menu *menu, int index);
206 MenuRedrawFlags menu_move_selection(struct Menu *menu, int index);
207 void menu_queue_redraw(struct Menu *menu, MenuRedrawFlags redraw);
208 MenuRedrawFlags menu_move_view_relative(struct Menu *menu, int relative);
209 MenuRedrawFlags menu_set_and_notify(struct Menu *menu, int top, int index);
210 void menu_adjust(struct Menu *menu);
211 
212 #endif /* MUTT_MENU_LIB_H */
213