This function allocates memory for a list box and initialises the objects by calling the routine <set> for each object passed in <objs>. However the list box will not be drawn!
Bit 0 of the variable <flags> determines whether the list box is a horizontal one (the first list item at left and last at right) or a vertical one (the first list item at top and last at bottom). Independently of this main scrolling direction the list box can also have a second slider if the items themselves are to be scrolled. This can be sensible, for instance, with a vertical list box with text items that are wider than the box.
Declaration: LIST_BOX *lbox_create( OBJECT *tree, SLCT_ITEM slct, SET_ITEM set, LBOX_ITEM *items, WORD visible_a, WORD first_a, WORD *ctrl_objs, WORD *objs, WORD flags, WORD pause_a, void *user_data, DIALOG *dialog, visible_b, first_b, entries_b, pause_b ); Call: box = lbox_create( tree, slct_item, set_item, item_list, 10, 0, ctrl_objs, objs, lbox_flags, 20, 0L, 0L, 10, 0, 40, 5 ); Variable Argument Meaning Inputs: contrl[0] 170 lbox_create contrl[1] 4 or 8 Entries in intin contrl[3] 8 Entries in addrin intin[0] visible_a Number of visible entries (Slider A) intin[1] first_a Index of the first visible entry (Slider A) intin[2] flags Various flags intin[3] pause_a Delay during scrolling in ms (Slider A) intin[4] visible_b Number of visible items (Slider B) intin[5] first_b First visible item (Slider B) intin[6] entries_b Number of items (Slider B) intin[7] pause_b Delay during scrolling in ms (Slider B) addrin[0] tree Pointer to the object tree of the dialog addrin[1] slct Pointer to selection routine addrin[2] set Pointer to set routine addrin[3] items Pointer to linked list with LBOX_ITEMs addrin[4] ctrl_objs Pointer to a field with the object numbers of the buttons and slider (5 entries) addrin[5] objs Pointer to a field with the object numbers of the list box items (<entries> entries) addrin[6] user_data Pointer for application addrin[7] dialog Pointer to the window dialog structure or 0L Outputs: contrl[2] 0 Entries in intout contrl[4] 1 Entries in addrout addrout[0] box Pointer to the list box structure or 0L
Both <slct> and <set> are functions whose parameters are passed on the stack. The functions may alter registers d0-d2/a0-a2.
<slct> is a pointer to a selection routine that is always called when an entry is selected or deselected:
typedef void (cdecl *SLCT_ITEM)( LIST_BOX *box, OBJECT *tree, struct _lbox_item *item, void *user_data, WORD obj_index, WORD last_state );
<box> | points to the list box structure |
<tree> | points to the object tree of the dialog |
<item> | points to the LBOX_ITEM-structure of the selected entry |
<user_data> | is the pointer passed by lbox_create() |
<obj_index> | is the number of the selected object. For a double-click |
the top bit is set, similar to form_do(). If <obj_index> | |
is 0 it signifies that no object is assigned to this entry; it is | |
not visible. Normally this only the case when one is scrolling | |
and by selecting a new object the (now no longer visible) | |
selection has to be cleared. | |
<last_state> | is the previous status of the object. <last_state> can also |
have the same value as <item->selected>. In that case | |
one can normally quit the function <slct> immediately. |
<slct> will also be called when the selection of an object is cleared! The variable <selected> from the LBOX_ITEM structure already contains the new status of the object when <slct> is called.
<set> points to the function that is to enter the contents of a LBOX_ITEM into an object of the list box dialog:
typedef WORD (cdecl *SET_ITEM)( LIST_BOX *box, OBJECT *tree, struct _lbox_item *item, WORD obj_index, void *user_data, GRECT *rect, WORD first );
<box> | points to the list box structure |
<tree> | points to the object tree of the dialog |
<item> | points to the LBOX_ITEM structure of the entry to be set |
<obj_index> | is the number of the object to be set |
<user_data> | is the pointer passed by lbox_create() |
<rect> | is the pointer to the GRECT for the object redraw or 0L |
<first> | contains the number of the first visible item for Slider B |
For a list box that only contains text strings, <set> is typically a function that copies a string pointed to by the LBOX_ITEM structure into the object <index>.
<rect> ist 0L when a redraw of the dialog box is executed or when lbox_update() has been called.
<rect> is not 0L when the user has selected or deselected an object, and points to the GRECT for the redraw. The return value of <set> is the number of the start object for objc_draw()/wdlg_redraw(). For entries in the list box that consist of several objects it is sometimes sensible to reduce the redraw rectangle when selecting/deselecting an object, or to alter the start object, to prevent unnecessary drawing operations and/or unnecessary flicker.
In most cases the list box routines call the function objc_draw()/wdlg_redraw() after <set> to display the altered contents.
<first> contains the number of the first visible item for Slider B if the list box has two sliders. For a (vertical) list box with text strings and two sliders, when calling lbox_create(), for instance, one enters the number of visible characters in <visible_b>, the total string length in <entries_b> and the index of the first visible character in <first_b>. If the text is scrolled horizontally, <set> is called for all visible strings and the affected parts of the screen are redrawn or moved. If the list box has only one slider, <first> is always 0.
<items> points to the first item in a list from LBOX_ITEM. The structure used for the items must contain a pointer to its successor (next) as its first element and a word for the condition (selected) as the second:
typedef struct _lbox_item { struct _lbox_item *next; /* Pointer to the next entry in the list */ WORD selected; /* Specifies whether the object is selected */ WORD data1; /* Data for the program... */ void *data2; void *data3; } LBOX_ITEM;
However the structure can well look like the following example with appropriate casting during the call:
typedef struct { void *next; WORD selected; ... From here on to suit the application ... } LB_EXAMPLE;
<ctrl_objs> is a pointer to a field with 5 or 9 entries that contains the numbers of the control objects (buttons):
ctrl_objs[0]: | Object number of the BOX or IBOX, that contains the |
actual list box object | |
ctrl_objs[1]: | Object number of the buttons for scrolling upwards or |
left | |
ctrl_objs[2]: | Object number of the buttons for scrolling downwards or |
right | |
ctrl_objs[3]: | Object number of the slider background box |
ctrl_objs[4]: | Object number of the slider box |
If the list box has 2 sliders, ctrl_objs[5-8] contain the numbers of the objects for Slider B:
ctrl_objs[5]: | Object number of the button for scrolling upwards or left |
ctrl_objs[6]: | Object number of the button for scrolling downwards or right |
ctrl_objs[7]: | Object number of the slider background box |
ctrl_objs[8]: | Object number of the slider box |
The buttons, the slider and the slider background should have a TOUCHEXIT status. If the list box contains only buttons and no slider, ctrl_objs[3/4 or 7/8] must contain -1.
<objs> is a field with <entries> entries that contains the numbers of the list box objects (the objects are normally children of ctrl_objs[0]).
objs[0]: Number of the first object . . . objs[entries - 1]: Number of the last object
The objects should normally have TOUCHEXIT status.
The word <flags> influences the behaviour of the list box:
Bit | State | Description |
0 | 0 | The box scrolls horizontally |
1 | The box scrolls vertically | |
1 | 0 | No automatic scrolling |
1 | Scrolling takes place automatically as soon as the mouse | |
cursor is moved past the first or last item with the mouse | ||
button held down | ||
2 | 0 | The selection routine will be called only after the |
automatic scrolling has finished, i.e. it will be called | ||
for the last selected entry | ||
1 | With automatic scrolling the selection routine will be | |
called for each selected entry during scrolling | ||
3 | 0 | When moving the slider a frame will be moved |
(graf_slidebox), the list box will only be updated | ||
after releasing the mouse button | ||
1 | The slider is a real-time slider | |
4 | 0 | Multiple selections within the list box are possible |
1 | Only one item can be selected | |
5 | 0 | Multiple selections are possible without the Shift key |
1 | Multiple selections are only possible with the Shift key | |
6 | 0 | On selection the status is always SELECTED |
1 | On selection the status is always changed | |
7 | 0 | The list box has only one slider |
1 | The list box has two sliders |
#define LBOX_VERT 1 /* List box with vertical slider */ #define LBOX_AUTO 2 /* Auto scrolling */ #define LBOX_AUTOSLCT 4 /* Automatic display during auto scrolling */ #define LBOX_REAL 8 /* Real-time slider */ #define LBOX_SNGL 16 /* Only one selectable entry */ #define LBOX_SHFT 32 /* Multiple selections with Shift */ #define LBOX_TOGGLE 64 /* On selection change status of an entry */ #define LBOX_2SLDRS 128 /* Support 2 sliders */
The flag LBOX_SNGL can also be combined with LBOX_SHFT or LBOX_TOGGLE to permit deselection in a list box with only one selectable entry. LBOX_SNGL + LBOX_SHFT means that the selected entry can be deselected by a click with a pressed Shift key. LBOX_SNGL + LBOX_TOGGLE causes a click to deselect a selected entry.
The pointer <items> can also be 0L if the list box is still empty and does not contain any entries.