/* * menuitem.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, Scott Scriven * 2004, F5 Networks, Inc. - IP-address input * 2005, Peter Marschall - error checks, ... * * 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. */ #ifndef MENUITEM_H #define MENUITEM_H #include "shared/LL.h" #ifndef bool # define bool short # define true 1 # define false 0 #endif #define max(a,b) (((a) > (b)) ? (a) : (b)) /********************************************************************* * Data definitions of the menustuff */ /** These values are used in the function tables in menuitem.c ! */ typedef enum MenuItemType { 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 */ typedef enum MenuToken { MENUTOKEN_MENU, MENUTOKEN_ENTER, MENUTOKEN_UP, MENUTOKEN_DOWN, MENUTOKEN_LEFT, MENUTOKEN_RIGHT, MENUTOKEN_OTHER } 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_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; #include "screen.h" /********************************************************************* * 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, char * key, bool extended); /** 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