map_bar_choose()

Purpose

Selects an option from an action-bar menu that has pull-down menus

Old name

#define actionbar(mapnr,option,banned_list)
map_bar_choose(mapnr,option,0,0,banned_list)

Syntax

int map_bar_choose(int mapnr,int DP4P option,int
flags, void (*draw_extra)(int mapnr),const short DP4P banned_list);

Parameters

int mapnr

Map number of the menu bar. This map must be on screen before making the call to map_bar_choose(). Although map_bar_choose() does not display the menu bar map initially, it does redraw the menu bar occasionally (using the map_draw_over() function with the flag NO_REARRANGE because of the need to colour menu bar fields

 

int *option

Pointer to an integer variable in which the selected option is returned. The initial value of this variable determines which option is highlighted to start with

 

int flags

Currently three flags are implemented:

 

HAS_PULL_DOWN

Enables a second level of pulldown menus

 

PULL_DOWN

Allows the user to escape from the whole menu as if it were a pulldown (by clicking outside it)

 

FUNC_KEYS

Enables function keys. These are not allowed to select options. Pressing a function key causes map_bar_choose() to return the value of the function key as its return value in abort_code

 

void (*draw_extra)()

If a non-zero value is passed for draw_extra, it is a pointer to a function called each time a map is drawn. This enables additional information to be displayed in the maps. The most likely use of this is to indicate 'check states' of particular options

 

short * banned_list

Pointer to a banned list of field options to grey out. This should point to an array of field numbers terminating in zero

Description

map_bar_choose() provides a simple mechanism to select an option from a menu bar with pulldown menus.

When your program runs, map_bar_choose() first does any necessary greying out, then highlights the initial option. The cursor keys, mnemonics and other usual means are available for the user to select options. Pulldown menus are displayed and greyed out as necessary. The selected option is returned in the integer variable option_nr.

The option number is returned by combining the field selected from the menu bar (the X co-ordinate) with the field selected from the pulldown menu (the Y co-ordinate) as (16*X)+Y. Assuming you have no more than nine options in the menu bar, or in each pulldown, it is easiest to code the actions selected using a switch statement with the cases coded in hex, as in:

if (!map_bar_choose(1,&option,0,0,banned_list))
switch (option)
{
case 0x11:
/* selects option 1 of pull down 1 */
case 0x12:
/* selects option 2 of pull down 1 */
case 0x21:
/* selects option 1 of pull down 2 */
}

Consider these points:

  • Options for greying out are numbered in the same way
  • If option is greater than 16, the appropriate pulldown is displayed and the relevant option highlighted, if it is less than 16 the cursor starts on the corresponding field of the menu bar
  • map_bar_choose() clears any pulldown it draws but leaves the menu bar on screen

From v 4.613 it is possible to add a second level of pulldowns to menus. In other words, an option in a pulldown menu leads to its own pulldown menu. You must pass the flag HAS_PULL_DOWN to enable a second level of pulldowns.

Where there are two levels of pulldowns, the option number is calculated as (256*x) + (16*y) + z, where x is the number of the menu in the menu bar, y is the number of the option from that menu and z is the number of the option from the sub-menu.

Return values

map_bar_choose() returns 0 if the user makes a choice or ESCAPE if <Esc> is pressed. If an activating function key is pressed or the FUNC_KEYS flag is set, the return value is the function key number.

Designing a Menu Bar with Pulldown Menus

The principal effort in providing a menu bar lies with the map design. But this follows a fixed pattern and is quickly achieved using the MAPEDIT utility. The pulldown menu system used for the QABUTIL utility is currently map 230 from the PROGMAKE mapset on the system database and can be examined to see the general layout.

To create a pulldown menu system, use MAPEDIT to create the menu bar and add the top level fields.

To add a pulldown menu for option <n> you select the Pull Down option within MAPEDIT. When you do so, MAPEDIT automatically adds a field 100+<n> in the correct position on the map and opens a menu edit window for the creation of the pulldown menu. If the menu bar map number is <m>, the pulldown menu for option <n> is given the map number <m>+<n>. map_bar_choose() attaches the pulldown menu to the field numbered 100+<n>.

A maximum of 15 options is allowed in the menu bar as well as in each pulldown menu.

Adhere to these guidelines when designing menu bars that conform to the IBM SAA (text mode) convention:

  • Start the first menu bar option in column 3. Use two spaces to separate options. The field for each option begins one space before the text and ends one space after it. Options are not numbered
  • Locate field 100+<n> one line below, and two spaces to the left of, field <n> (field 100+<n> defines the pulldown menu's position)
  • The pulldown menus are normal menus with numbered options of the same width. The numbers are separated from their options either by two spaces or a full stop and a space. The menu appears in a box with one space between the edge of the box at either side and the fields

To conform with Windows the rules are different:

  • The first menu bar option begins in column 1. Use two spaces to separate options. The field for each option begins one space before the text and ends one space after it. Options are not numbered
  • Locate field 100+<n> one line below, and in the same column as, field <n>
  • The pulldown menus are normal menus without option numbers. Each option is the same width. The menu is in a box with one space between the edge of the box at either side and the fields

Example

/*
C Functions Reference Manual
----------------------------
Filename: MAP_BAR_.C
Example: map_bar_choose
Purpose: Simple example showing how to display an
action ban using map_bar_choose.
*/

/*
#db salesord
#c
#end
*/
#include "dp4.h"
#include "map_bar_.h"
/* generate this file by running LIBMAKE */
/* prototypes */
int act_option(int*);
void init_ban(void);
short DP4P banned_list(void);
void grey_out(int, int);

void new_cust(void);
void rem_cust(void);
void cust_enq(void);
void ord_enq(void);
void new_ord(void);
void new_reg(void);
void edit_reg(void);
void del_reg(void);
void aval_mat(void);
void chk_lev(void);

void process()
{
int option = 1; /* header map */
map_draw(1,RETAIN); /* action bar menu map */
init_ban();
for(;;)
{
map_clear_after(1);
map_draw(2, RETAIN|MENUMAP);
/* if user presses Esc goto escape option */
if (map_bar_choose(2,(int DP4P)&option,
PULL_DOWN,0,banned_list()))
option = (option == 5) ? 0x51: 5;
else if (act_option(&option)) break;
}
}

int act_option(int* option)
/* act on option from action bar */
{
switch (*option)
{
/* customer menu */
case 0x11:
new_cust();
break;
case 0x12:
rem_cust();
break;
case 0x13:
cust_enq();
break;
case 0x18: /* Exit */
*option = 1;
break;
/* order menu*/
case 0x21:
ord_enq();
break;
case 0x22:
new_ord();
break;
case 0x28: /* Exit */
*option = 2;
break;
/* region menu */
case 0x31:
new_reg();
break;
case 0x32:
edit_reg();
break;
case 0x33:
del_reg();
break;
case 0x38:
/* Exit */
*option = 3;
break;
/* material menu */
case 0x41:
aval_mat();
break;
case 0x42:
chk_lev();
break;
case 0x48:
/* Exit */
*option = 4;
break;
/* exit menu */
case 0x51:
return TRUE;
case 0x58:
/* Exit */
*option = 5;
break;
default:
break;
}
return FALSE;
}

/* banned options module */
static int ban[24];
static int ban_nr;

void init_ban()
{
ban_nr = 0;
ban[0] = 0;
}
short DP4P banned_list()
{
return ban;
}

void grey_out(int option,int put_on)
/* grey out */
{
register int i = 0;

/* check if already on list */
while (ban[i] != 0)
{
if (ban[i] == option)
{
if (put_on)
return;
else
{
movmem(ban+i+1, ban+i, ban_nr-i);
ban_nr--;
return;
}
}
i++;
}
/* put on end */
if (put_on)
{
ban[i++] = option;
ban_nr++;
ban[i] = 0;
}
}

/* support functions - just display a map*/

void new_cust()
{
map_pause(50);
}

void rem_cust()
{
map_pause(51);
}

void cust_enq()
{
map_pause(52);
}

void ord_enq()
{
map_pause(53);
}

void new_ord()
{
map_pause(54);
}

void new_reg()
{
map_pause(55);
}

void edit_reg()
{
map_pause(56);
}

void del_reg()
{
map_pause(57);
}

void aval_mat()
{
map_pause(58);
}

void chk_lev()
{
map_pause(59);
}