3 * Copyright (c) 2007 Pete Mack and others
4 * This code released under the Gnu Public License. See www.fsf.org
5 * for current GPL license details. Addition permission granted to
6 * incorporate modifications in all Angband variants as defined in the
7 * Angband variants FAQ. See rec.games.roguelike.angband for FAQ.
15 /* ============= Constants ============ */
18 /* Colors for interactive menus */
20 CURS_UNKNOWN
= 0, /* Use gray; dark blue for cursor */
21 CURS_KNOWN
= 1 /* Use white; light blue for cursor */
23 static const byte curs_attrs
[2][2] =
25 {TERM_SLATE
, TERM_BLUE
}, /* Greyed row */
26 {TERM_WHITE
, TERM_L_BLUE
} /* Valid row */
29 /* Standard menu orderings */
30 extern const char default_choice
[]; /* 1234567890A-Za-z */
31 extern const char lower_case
[]; /* abc..z */
32 extern const char upper_case
[]; /* ABC..Z */
37 /* ============= Defines a visual grouping ============ */
44 /* ================== GEOMETRY ====================== */
46 /* Defines a rectangle on the screen that is bound to a Panel or subpanel */
47 typedef struct region region
;
50 int col
; /* x-coordinate of upper right corner */
51 int row
; /* y-coord of upper right coordinate */
52 int width
; /* width of display area. 1 - use system default. */
53 /* non-positive - rel to right of screen */
54 int page_rows
; /* non-positive value is relative to the bottom of the screen */
57 /* Region that defines the full screen */
58 static const region SCREEN_REGION
= {0, 0, 0, 0};
60 /* Erase the contents of a region */
61 void region_erase(const region
*loc
);
62 /* Check whether a (mouse) event is inside a region */
63 bool region_inside(const region
*loc
, const event_type
*key
);
67 /* =================== EVENTS =================== */
70 typedef struct event_target event_target
;
71 typedef struct event_listener event_listener
;
72 typedef struct event_set event_set
;
73 typedef struct listener_list listener_list
; /* Opaque */
75 /* An event handler member function */
76 typedef bool (*handler_f
)(void *object
, const event_type
*in
);
78 /* Frees the resources for an owned event listener */
79 typedef void (*release_f
)(void *object
);
81 /* Set of event types to which a particular listener has subscribed */
83 int evt_flags
; /* OR'ed together set of events */
87 /* Base class for event listener */
90 int object_id
; /* Identifier used for macros, etc */
91 handler_f handler
; /* The handler function to call */
92 release_f release
; /* Frees any owned resources */
93 void *object
; /* Self-pointer */
95 /* properly, this belongs in the listener_list */
96 event_set events
; /* Set of events to which this listener has subscribed */
100 /* Event target -- the owner for a list of event listeners */
101 /* Examples include Windows, Panels (menus), application */
102 struct event_target
{
103 /* Allow a target to be a listener as well */
106 listener_list
*observers
;
109 void add_listener (event_target
*parent
, event_listener
*child
);
110 void add_target(event_target
*parent
, event_target
*child
);
112 void remove_listener (event_target
*parent
, event_listener
*child
);
113 event_type
run_event_loop(event_target
*parent
, bool forever
, const event_type
*start
);
115 /* Forward declare */
116 /* RISC OS already has a menu_item and menu_flags in system library */
118 #define menu_item ang_menu_item
119 #define menu_flags ang_menu_flags
122 typedef struct event_action event_action
;
123 typedef struct menu_item menu_item
;
124 typedef struct menu_type menu_type
;
125 typedef struct menu_skin menu_skin
;
126 typedef struct menu_iter menu_iter
;
129 /* ================= PANEL ============ */
130 typedef struct panel_type panel_type
;
133 * An event target bound to a particular screen area.
134 * A Panel is a (rectangular) (sub)region, possibly containing a set of event
135 * listeners, and responsible for maintaining its own internal layout and
136 * dispatching. A Panel has ownership of a Region, is a Container for Event Listeners,
137 * and an Event Target for mouse events).
138 * Potential examples include:
146 void (*refresh
)(menu_type
*);
150 /* ================== MENUS ================= */
154 * Performs an action on object with an optional environment label
155 * Member function of "menu_iter" VTAB
157 typedef void (*action_f
)(void *object
, const char *name
);
160 * Displays a single row in a menu
161 * Driver function for populating a single menu row.
162 * Member function for "menu_iter" VTAB
164 typedef void (*display_row_f
) (menu_type
*menu
, int pos
,
165 bool cursor
, int row
, int col
, int width
);
168 * Driver function for displaying a page of rows.
169 * Member function of "menu_skin" VTAB
171 typedef void (*display_list_f
)(menu_type
*menu
, int cursor
, int *top
, region
*);
174 /* Primitive menu item with bound action */
177 int id
; /* Object id used to define macros &c */
178 const char *name
; /* Name of the action */
179 action_f action
; /* Action to perform, if any */
180 void *data
; /* Local environment for the action, if required */
184 /* Decorated menu item with bound action */
187 event_action evt
; /* Base type */
188 char sel
; /* Character used for selection, if special-purpose bindings */
190 int flags
; /* State of the menu item. See enum menu_flags below */
194 /* TODO: menu registry */
196 Together, these classes define the constant properties of
197 the various menu classes.
199 - menu_iter, which describes the basic
200 class on which the menu is operating
202 MN_EVT- event_action array,
203 MN_ACTION - menu_item array,
204 MN_DBVIEW - general db iterator
206 - a menu_skin, which describes the layout of the menu on the screen.
208 MN_COLUMNS - all rows shown at once, in mult-column output.
209 MN_SCROLL - only a limited part of the menu is shown, in a scrollable
211 MN_NATIVE - not implemented (OS menu)
212 Menus also require data-dependent functions:
218 /* Appearance & behavior */
220 MN_REL_TAGS
= 0x0100, /* Tags are associated with the view, not the element */
221 MN_NO_TAGS
= 0x0200, /* No tags -- movement key and mouse browsing only */
222 MN_PVT_TAGS
= 0x0400, /* Tags to be generated by the display function */
223 MN_CASELESS_TAGS
= 0x0800, /* Tag selections can be made regardless of the case of the key pressed. - i.e. 'a' activates the line tagges 'A'. */
225 MN_DBL_TAP
= 0x1000, /* double tap for selection; single tap is cursor movement */
226 MN_NO_ACT
= 0x2000, /* Do not invoke the specified action; menu selection only */
227 MN_PAGE
= 0x4000, /* Use full-page scrolling rather than small increment */
228 MN_NO_CURSOR
= 0x8000, /* No cursor movement */
230 /* Reserved for rows in action_menu structure. */
231 MN_DISABLED
= 0x0100000, /* Neither action nor selection is permitted */
232 MN_GRAYED
= 0x0200000, /* Row is displayed with CURS_UNKNOWN colors */
233 MN_GREYED
= 0x0200000, /* Row is displayed with CURS_UNKNOWN colors */
234 MN_SELECTED
= 0x0400000, /* Row is currently selected */
235 MN_SELECTABLE
= 0x0800000, /* Row is permitted to be selected */
236 MN_HIDDEN
= 0x1000000 /* Row is hidden, but may be selected via */
240 /* Identifier for the type of menu layout to use */
244 MN_SCROLL
= 0x0000, /* Ordinary scrollable single-column list */
245 MN_COLUMNS
= 0x0002, /* multicolumn view */
246 MN_NATIVE
= 0x0003, /* Not implemented -- OS menu */
247 MN_KEY_ONLY
= 0x0004, /* No display */
248 MN_USER
= 0x0005 /* Anonymous, user defined. */
251 /* Class functions for menu layout */
253 skin_id id
; /* Identifier from the above list */
254 /* Determines the cursor index given a (mouse) location */
255 int (*get_cursor
)(int row
, int col
, int n
, int top
, region
*loc
);
256 /* Displays the current list of visible menu items */
257 display_list_f display_list
;
258 /* Specifies the relative menu item given the state of the menu */
259 char (*get_tag
)(menu_type
*menu
, int pos
);
260 /* Superclass pointer. Not currently used */
261 const menu_skin
*super
;
265 /* Identifiers for canned row iterator implementations */
268 MN_ACT
= 0x1, /* selectable menu with per-row flags (see below) */
269 MN_EVT
= 0x2, /* simple event action list */
270 MN_STRING
= 0x3 /* display an array of strings for selection */
274 /* Class functions for menu row-level accessor functions */
276 menu_iter_id id
; /* Type identifier from above set */
277 /* Optional selection tag function */
278 char (*get_tag
)(menu_type
*menu
, int oid
);
279 /* Optional validity checker. All rows are assumed valid if not present. */
280 /* To support "hidden" items, it uses 3-level logic: 0 = no 1 = yes 2 = hide */
281 int (*valid_row
)(menu_type
*menu
, int oid
);
282 /* Displays a menu row at specified location */
283 display_row_f display_row
;
284 /* Handler function called for selection or command key events */
285 bool (*row_handler
)(char cmd
, void *db
, int oid
);
289 /* A menu defines either an action
294 /* menu inherits from panel */
299 /* set of commands that may be performed on a menu item */
300 const char *cmd_keys
;
303 /* Public variables */
308 /* Keyboard shortcuts for menu selection */
309 /* IMPORTANT: this cannot intersect with cmd_keys */
310 const char *selections
;
312 /* Flags specifying the behavior of this menu. See enum MENU_FLAGS */
314 int filter_count
; /* number of rows in current view */
315 const int *object_list
; /* optional filter (view) of menu objects */
316 int count
; /* number of rows in underlying data set */
317 const void *menu_data
; /* the data used to access rows. */
319 /* auxiliary browser help function */
320 void (*browse_hook
)(int oid
, void *db
, const region
*loc
);
323 /* These are "protected" - not visible for canned menu classes, */
324 /* The per-row functions */
325 const menu_iter
*row_funcs
;
328 /* State variables for the menu */
329 int cursor
; /* Currently selected row */
330 int top
; /* Position in list for partial display */
331 region active
; /* Subregion actually active for selection */
333 /* helper functions for layout information. */
334 const menu_skin
*skin
; /* Defines menu appearance */
339 * Select a row from a menu.
342 * object_list - optional ordered subset of menu OID. If NULL, cursor is used for OID
343 * cursor - current (absolute) position in menu. Modified on selection.
344 * loc - location to display the menu.
345 * Return: A command key; cursor is set to the corresponding row.
346 * (This is a stand-in for a menu event)
347 * reserved commands are 0xff for selection and ESCAPE for escape.
349 event_type
menu_select(menu_type
*menu
, int *cursor
, int no_handle
);
351 /* TODO: This belongs in the VTAB */
352 bool menu_layout(menu_type
*menu
, const region
*loc
);
354 /* accessor & utility functions */
355 void menu_set_filter(menu_type
*menu
, const int object_list
[], int n
);
356 void menu_release_filter(menu_type
*menu
);
357 void menu_set_id(menu_type
*menu
, int id
);
359 /* Set up structures for canned menu actions */
360 /* Bind the vtab for a menu */
361 bool menu_init(menu_type
*menu
, skin_id skin
, menu_iter_id iter
,
364 /* Initialize a menu given (anonymous) menu iter */
365 bool menu_init2(menu_type
*menu
, const menu_skin
*skin
,
366 const menu_iter
*iter
, const region
*loc
);
368 void menu_refresh(menu_type
*menu
);
369 void menu_destroy(menu_type
*menu
);
371 /* Menu VTAB registry */
372 const menu_iter
*find_menu_iter(menu_iter_id iter_id
);
373 const menu_skin
*find_menu_skin(skin_id skin_id
);
375 void add_menu_skin(const menu_skin
*skin
, skin_id id
);
376 void add_menu_iter(const menu_iter
*skin
, menu_iter_id id
);
384 void window_make(int origin_x
, int origin_y
, int end_x
, int end_y
);