File: menuitem.h

package info (click to toggle)
lcdproc 0.5.9-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 5,064 kB
  • sloc: ansic: 59,645; sh: 1,740; perl: 681; makefile: 417
file content (332 lines) | stat: -rw-r--r-- 11,981 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
/** \file server/menuitem.h
 * Defines all the menuitem data and actions.
 *
 * There are a few different menuitems:
 * - action
 * - checkbox (on/off and optionally open)
 * - slider (the user can increase/decrease a value)
 * - numeric input
 * - alphanumeric input (in short: alpha)
 * - menu (a menu is a menuitem itself too)
 *
 * The slider, numeric & string input and menu have their own screen,
 * that comes to front when the items are selected.
 * One menuitem is in a different file: Menu data is in menu.h.
 */

/* This file is part of LCDd, the lcdproc server.
 *
 * This file is released under the GNU General Public License.
 * Refer to the COPYING file distributed with this package.
 *
 * Copyright (c) 1999, William Ferrell, Selene Scriven
 *               2004, F5 Networks, Inc. - IP-address input
 *               2005, Peter Marschall - error checks, ...
 */

#ifndef MENUITEM_H
#define MENUITEM_H

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_STDBOOL_H
# include <stdbool.h>
#endif
#include "shared/defines.h"

#include "shared/LL.h"

extern bool menu_permissive_goto; /* Flag from the configuration file */

/*********************************************************************
 * Data definitions of the menustuff
 */

/** These values are used in the function tables in menuitem.c ! */
typedef enum MenuItemType {
	MENUITEM_INVALID  = -1,
	MENUITEM_MENU     = 0,
	MENUITEM_ACTION   = 1,
	MENUITEM_CHECKBOX = 2,
	MENUITEM_RING     = 3,
	MENUITEM_SLIDER   = 4,
	MENUITEM_NUMERIC  = 5,
	MENUITEM_ALPHA    = 6,
	MENUITEM_IP       = 7,
        NUM_ITEMTYPES = 8
} MenuItemType;

typedef enum CheckboxValue {
	CHECKBOX_OFF = 0, CHECKBOX_ON, CHECKBOX_GRAY
} CheckboxValue;

/** Recognized input token codes: they need to be bit values */
typedef enum MenuToken {
	MENUTOKEN_NONE  = 0x0000,	/**< no key */
	MENUTOKEN_MENU  = 0x0001,	/**< MenuKey */
	MENUTOKEN_ENTER = 0x0002,	/**< EnterKey */
	MENUTOKEN_UP    = 0x0004,	/**< UpKey */
	MENUTOKEN_DOWN  = 0x0008,	/**< DownKey */
	MENUTOKEN_LEFT  = 0x0010,	/**< LeftKey */
	MENUTOKEN_RIGHT = 0x0020,	/**< RightKey */
	MENUTOKEN_OTHER = 0x1000	/**< any other key */
} MenuToken;

/** Return codes from an input handler */
typedef enum MenuResult {
	MENURESULT_ERROR = -1,	/**< Something has gone wrong */
	MENURESULT_NONE  = 0,	/**< Token handled OK, no extra action */
	MENURESULT_ENTER,	/**< Token handled OK, enter the selected
				 * menuitem now */
	MENURESULT_CLOSE,	/**< Token handled OK, close the current
				 * menuitem now */
	MENURESULT_QUIT,	/**< Token handled OK, close ALL menus now */
	MENURESULT_PREDECESSOR, /**< Token handled OK, goto registered
				 * predecessor */
	MENURESULT_SUCCESSOR    /**< Token handled OK, goto registered
				 * successor */
} MenuResult;

/** Events caused by a menuitem */
typedef enum MenuEventType {
	MENUEVENT_INVALID = -1,	/**< Special value for error handling */
	MENUEVENT_SELECT = 0,	/**< Item has been selected
				 * (action chosen) */
	MENUEVENT_UPDATE = 1,	/**< Item has been modified
				 * (checkbox, numeric, alphanumeric) */
	MENUEVENT_PLUS   = 2,	/**< Item has been modified in positive direction
				 * (slider moved) */
	MENUEVENT_MINUS  = 3,	/**< Item has been modified in negative direction
				 * (slider moved) */
	MENUEVENT_ENTER  = 4,	/**< Menu has been entered */
	MENUEVENT_LEAVE  = 5,	/**< Menu has been left */
	NUM_EVENTTYPES   = 6
} MenuEventType;

#define MenuEventFunc(f) int (f) (struct MenuItem *item, MenuEventType event)

/** I've used a union in the struct below. Why? And why not for Widget?
 *
 * There are different types of menuitems. There are also types of widgets.
 * Menuitems have, just like widgets, different datafields per subtype.
 * The difference is that menuitems have, unlike widgets _many__different_
 * attributes. Widgets share many attributes like x, y, text.
 * The code would become unreadable if we used the 'widget way', or it would
 * get large if we define datafields that we use for only one type of
 * menuitem. (Joris)
 */
typedef struct MenuItem {
	MenuItemType type;	/**< Type as defined above */
	char *id;		/**< Internal name for client supplied menus */
	char *successor_id;	/**< next menuitem after hitting "Enter" on
				 * this one. (Special values are "_quit_",
				 * "_close_", "_none_"). */
	char *predecessor_id;	/**< next menuitem after hitting "Escape" on
				 * this one. (Special values are "_quit_",
				 * "_close_", "_none_"). */
	struct MenuItem *parent; /**< Parent of this menuitem */
	MenuEventFunc (*event_func);
			/**< Defines event_func to be an event function */
	char *text;	/**< Visible name of the item */
	void* client;	/**< The owner of this menuitem. */
	bool is_hidden; /**< If the item currently should not appear in a menu. */
	union data {
		struct menu {
			int selector_pos;	/**< At what menuitem is the
						   selector (0 for first) */
			int scroll;		/**< How much has the menu been
						   scrolled down */
			void *association;      /**< To associate an object
                                                   with this menu */
			LinkedList *contents;	/**< What's in this menu */
		} menu;
		struct action {
			/* nothing */
		} action;
		struct checkbox {
			bool allow_gray;	/**< Is CHECKBOX_GRAY allowed ? */
			CheckboxValue value;	/**< Current value */
		} checkbox;
		struct ring {
			LinkedList *strings;	/**< The selectable strings */
			short value;		/**< Current index */
		} ring;
		struct slider {
			char *mintext;		/**< Text at minimal value */
			char *maxtext;		/**< Text at minimal value */
			int minvalue;
			int maxvalue;
			int stepsize;
			int value;		/**< Current value */
		} slider;
		struct numeric {
			int maxvalue;
			int minvalue;
			//short allowed_decimals; /**< Number of numbers behind dot */
			int value;		/**< Current value */
			char *edit_str;		/**< Value while being edited */
			short edit_pos;		/**< Position while editing */
			short edit_offs;	/**< Offset while editing */
			short error_code;
		} numeric;
		struct alpha {
			char password_char;	/**< For passwords */
			short minlength;
			short maxlength;
			bool allow_caps;	/**< Caps allowed ? */
			bool allow_noncaps;	/**< Non-caps allowed ? */
			bool allow_numbers;	/**< Numbers allowed ? */
			char *allowed_extra;	/**< Allowed extra characters */
			char *value;		/**< Current value */
			char *edit_str;		/**< Value while being edited */
			short edit_pos;		/**< Position while editing */
			short edit_offs;	/**< Offset while editing */
			short error_code;
		} alpha;
		struct ip {
			char *value;		/**< Current value */
			char *edit_str;		/**< Value while being edited */
			short maxlength;
			bool v6;		/**< true if editing ipv6 addr */
			short edit_pos;		/**< Position while editing */
			short edit_offs;	/**< Offset while editing */
			short error_code;
		} ip;
	} data;
} MenuItem;


/*********************************************************************
 * Functions to use the menustuff
 */

/** translates a predecessor_id into a MenuResult. */
MenuResult menuitem_predecessor2menuresult(char *predecessor_id, MenuResult default_result);

/** translates a successor_id into a MenuResult. */
MenuResult menuitem_successor2menuresult(char *successor_id, MenuResult default_result);

MenuItem *menuitem_search(char *menu_id, Client *client);

/** YOU SHOULD NOT CALL THIS FUNCTION BUT THE TYPE SPECIFIC ONE INSTEAD */
MenuItem *menuitem_create(MenuItemType type, char *id,
		MenuEventFunc(*event_func), char *text, Client *client);

/* For all constructor functions below the following:
 *
 * id:		internal name of the item. Never visible. String will be
 *		copied.
 * event_func:	the event function that should be called upon actions on this
 *		item.
 * text:	the displayed text.
 *
 * All strings will be copied !
 *
 * Return value: the new item, or NULL on error.
 *
 * To create a Menu (which is also an ItemType), call menu_create.
 *
 */

/** Creates a an action item (a string only).  Generated events:
 * MENUEVENT_SELECT when user selects the item.
 */
MenuItem *menuitem_create_action(char *id, MenuEventFunc(*event_func),
	char *text, Client *client, MenuResult menu_result);

/** Creates a checkbox.
 * Generated events: MENUEVENT_UPDATE when user changes value (immediately).
 */
MenuItem *menuitem_create_checkbox(char *id, MenuEventFunc(*event_func),
	char *text, Client *client, bool allow_gray, bool value);

/** Creates a ring with the given string, separated by tabs.
 * value is the (initial) index in the strings.
 * eg: if strings="abc\\tdef" the value=1 means that "def" is selected.
 * Generated events: MENUEVENT_UPDATE when user changes value (immediately).
 */
MenuItem *menuitem_create_ring(char *id, MenuEventFunc(*event_func),
	char *text, Client *client, char *strings, short value);

/** Creates a slider with the given min and max values.
 * If the display is big enough the mintext and maxtext will be placed
 * at the end positions of the slider.
 * You can set the step size. Make it 0 to disable the automatic value chaning,
 * and update the value yourself.
 * MENUEVENT_PLUS, MENUEVENT_MINUS when slider is moved (immediately).
 */
MenuItem *menuitem_create_slider(char *id, MenuEventFunc(*event_func),
	char *text, Client *client, char *mintext, char *maxtext,
	int minvalue, int maxvalue, int stepsize, int value);

/** Creates a numeric value box.
 * Value can range from minvalue to maxvalue.
 * MENUEVENT_UPDATE when user finishes the value (no immediate update).
 */
MenuItem *menuitem_create_numeric(char *id, MenuEventFunc(*event_func),
	char *text, Client *client, int minvalue, int maxvalue, int value);

/** Creates a string value box.
 * Value should have given minimal and maximal length. You can set whether
 * caps, non-caps and numbers are allowed. Also you can alow other characters.
 * If password char is non-zero, you will only see this char, not the actual
 * input.
 * MENUEVENT_UPDATE when user finishes the value (no immediate update).
 */
MenuItem *menuitem_create_alpha(char *id, MenuEventFunc(*event_func),
	char *text, Client *client, char password_char, short minlength, short maxlength,
	bool allow_caps, bool allow_noncaps, bool allow_numbers,
	char *allowed_extra, char *value);

/** Creates an ip value box.  can be either v4 or v6
 * MENUEVENT_UPDATE when user finishes the value (no immediate update).
 */
MenuItem *menuitem_create_ip(char *id, MenuEventFunc(*event_func),
	char *text, Client *client, bool v6, char *value);

/** Deletes item from memory.
 * All allocated extra data (like strings) will be freed.
 */
void menuitem_destroy(MenuItem *item);

/** Resets the item to the initial state.
 * You should call menuitem_update after this to see the effects.
 * This call is useless on items that have immediate effect, like a slider.
 * Those items do not keep temporary data.
 */
void menuitem_reset(MenuItem *item);

/** (Re)builds the selected menuitem on screen using widgets.
 * Should be re-called if menuitem data has been changed.
 * There are a few (logical) exceptions to this:
 * - the values
 * - the menu scroll and menu index
 */
void menuitem_rebuild_screen(MenuItem *item, Screen *s);

/** Updates the widgets of the selected menuitem
 * Fills all widget attributes with the corrrect values.
 */
void menuitem_update_screen(MenuItem *item, Screen *s);

/** Does something with the given input.
 * key is only used if token is MENUTOKEN_OTHER.
 */
MenuResult menuitem_process_input(MenuItem *item, MenuToken token, const char *key, unsigned int keymask);

/** returns the Client that owns the MenuItem. item must not be null */
Client *menuitem_get_client(MenuItem *item);

/** Converts a tab-separated list to a LinkedList. */
LinkedList *tablist2linkedlist(char *strings);

MenuItemType menuitem_typename_to_type(char *name);

char *menuitem_type_to_typename(MenuItemType type);

MenuEventType menuitem_eventtypename_to_eventtype(char *name);

char *menuitem_eventtype_to_eventtypename(MenuEventType type);

#endif