The <menus.h> header file


  
This header file contains the following functions:
MenuAddIcon         MenuAddText         MenuBegin           MenuCheck
MenuEnd             MenuGetTopRedef     MenuKey             MenuNew
MenuOn              MenuPopup           MenuSubStat         MenuTopRedef
MenuTopSelect       MenuTopStat         MenuUpdate          PopupAddText
PopupClear          PopupDo             PopupNew            PopupText
and the following constants and predefined types:
Bool                CENTER              H_NULL              HANDLE
ICON                ItemTypes           NULL                pICON

Functions


HANDLE PopupNew (char *title, short height);

Creates a new popup menu.

PopupNew allocates a memory for a new popup menu, initializes allocated block with necessary structures and returns a handle to it (or H_NULL in a case of error). You can later free the memory by calling HeapFree. title is the title of the menu (you can pass NULL if you don't want a title), and height is the height of the menu box in pixels (it seems that you can pass 0 for autocalculating the height, but I don't know whether this is reliable). If the number of the items in the menu is greater than available height of the menu box, the menu content will scroll upwards or downwards if necessary.

NOTE: If title is longer than 18 chars, it will be truncated by storing a zero byte into the string after 18th char.

HANDLE PopupAddText (HANDLE Handle, short Link, char *text, unsigned short ret_val);

Adds a new text item in a popup menu.

PopupAddText adds the text text to the popup menu associated with handle Handle. The first added text will be the first option in the menu, the second added text will be the second option, etc. ret_val is the return value which PopupDo function will later return if the user select this menu option. If ret_val is 0, the TIOS will associate the return value automatically (1 to the first menu option, 2 to the second option, etc.). Legal range for ret_val is 1 to 4095. If ret_val is greater than 4095, it will be truncated (ANDed with 0x0FFF). Parameter Link has the following meaning: PopupAddText returns H_NULL in a case of error, else returns Handle. It may cause the heap compression. Although TIOS menu system allows menus with more than one level of submenus, it is not possible to create such menus using this command. If you really want more levels of nesting, you need to use pre-filled static structures and MenuPopup function. But, note that this is somewhat complicated.

NOTE: If text is longer than 18 chars, it will be truncated by storing a zero byte into the string after 18th char.

unsigned short PopupDo (HANDLE Handle, short x, short y, unsigned short start_option);

Executes a popup menu.

DialogDo draws the popup menu associated with handle Handle on the screen. The top-left corner of the dialog will be the at the position (xy), where coordinates are absolute screen coordinates. x, y or both may also have a special value CENTER which means "center the menu on the screen in x, y or both directions". After the execution, the original content of the screen will be restored. PopupDo returns ret_val of the selected menu item (see PopupAddText), or 0 if the user pressed ESC key. start_option determines which option will be selected first when the menu is executed (an option which has its ret_val equal to start_option will be selected at the beginning). It seems that start_option works correct only for menus without submenus. Anyway, you can pass 0 to start_option always. It means "select the first option", as usual. This routine may cause the heap compression.

Here is an example of the scrolling popup menu with submenus:
handle = PopupNew ("EXAMPLE", 40);
PopupAddText (handle, -1, "Option 1", 1);
PopupAddText (handle, -1, "Option 2", 2);
PopupAddText (handle, 0, "Submenu 3", 3);
PopupAddText (handle, 0, "Submenu 4", 4);
PopupAddText (handle, -1, "Option 5", 5);
PopupAddText (handle, 3, "Suboption 3.1", 6);
PopupAddText (handle, 3, "Suboption 3.2", 7);
PopupAddText (handle, 3, "Suboption 3.3", 8);
PopupAddText (handle, 4, "Suboption 4.1", 9);
result = PopupDo (handle, CENTER, CENTER, 0);

HANDLE PopupClear (HANDLE Handle);

Clears a popup menu structure.

PopupClear erases all menu items from the popup menu associated with handle Handle, without freeing the memory (the popup structure itself remains intact, only menu items are erased). Returns H_NULL in a case of error, else returns Handle.

NOTE: This function is very useful in menus which are part of dialogs, when some changes in a dialog box may force menu items to be repopulated (for example when the user selects a new folder in VAR-OPEN dialog). Since the dialog box code keeps the handle of the menu, a new one cannot be created. So the old popup menu is cleared and new entries are added to it. */

char *PopupText (HANDLE Handle, unsigned short ret_val);

Returns a pointer to the menu item.

PopupText returns the pointer to the text of the menu item which has return value ret_val (see PopupAddText). Handle is the handle associated to the menu.

unsigned short MenuPopup (void *MenuPtr, short x, short y, unsigned short start_option);

Executes a popup menu giving a pointer to a popup menu structure.

MenuPopup works exactly like PopupDo, except instead of the handle, a pointer to the menu structure is given as the parameter. PopupDo internally calls HeapDeref, then passes returned pointer to MenuPopup function. This function is manly used internally in TIOS. Its advance in comparing to PopupDo is in the fact that the complete popup menu structure may be given as a static pre-filled array of butes, and you can give the pointer to such structure to MenuPopup function. It will save a lot of memory, because you need not to call PopupNew, a lot of functions like PopupAddText etc. And, MenuPopup allows executing of menus with more than one level of submenus, which can not be created using PopupAddText etc. But note that the menu structure is a quite complicated variable-shape structure, so if you don't know EXACTLY what you are doing, avoid this function! As the menu structure is variable-length and variable-shape, it can not be strictly described as C-language type, but it will be described here using non-formal C-like syntax (note that toolbar menus use the same structure):
packed struct MENU
  {
    unsigned short DisplayOffset;  // Contains offset to Display[0] from here
    unsigned short Flags;          // Various flags: see text below
    unsigned short TotalItems;     // Total number of items
    unsigned char Width;           // Menu width, 0 for popup menus
    unsigned char Height;          // Menu height
    unsigned short MainItems;      // Number of main items only
    unsigned short DynSize;        // Dynamic size (see text below)
    unsigned short RedefOffset;    // Offset to RedefIcons, 0 if RedefItems = 0
    unsigned short RedefItems;     // Number of redefinable icons
    long separator = -1;

    MENU_ENTRY main_entries [];    // for each main item
    long separator = -1;

    struct
      {
        MENU_ENTRY sub_entries []; // for each submenu item
        long separator = -1;
      } cascade [];                // for each submenu

    packed union
      {
        ICON Icon;          // Used in toolbars with icons instead of texts
        char Text [];       // Text, zero terminated
      } Display [];         // for each menu item

    struct
      {
        unsigned short ID;  // ID number (retval of option assigned with icon)
        ICON Icon;          // Corresponding icon description
      } RedefIcons [];      // for each redefinable icons (if any)
  };
Field Flags contains various flags. I don't know their exact meaning, but what I know is that b7 and b6 should be set for popup menus, b4 should be set for menus with titles, b2 should be set for menus where return values for each item are given explicitely, and b0 should be set for menus where the height is given explicitely (else it will be calculated automatically). Field DynSize for dinamically created menus (i.e. menus created with PopupNew) contains the total length of the MENU structure in bytes (this info is needed for the heap manager). For statically alocated menus, you can put zero in this field. Also, each element of array Display [] should be aligned on word boundary. This is not strictly necessary for text items, but this is necessary for icon items.

Each menu item is descripted using a variable-length (4 or 6 bytes) structure called MENU_ENTRY, which is described as:
struct MENU_ENTRY
  {
    unsigned short ID;                // Item type (see below) ORed with
                                      //   return value for this item
    unsigned short Offset;            // Offset of icon/text (from Display[0])
                                      //   or XR_string, depending of item type
    packed union                      // If the item is cascaded (i.e if it has
      {                               //   a submenu), we have an extra offset
        unsigned short CascadeOffset; // Offset from the begining of menu
      } extras;                       //   structure to the begining of the
  };                                  //   description of the cascaded submenu
Possible item types are MT_TEXT (0x8000), MT_XREF (0x9000) and MT_ICON (0xA000). They may be eventually ORed with MT_CASCADE (0x4000) to signalize that the item is cascaded (i.e. that the item has a submenu). All these constants are defined in enum ItemTypes. So, field CascadeOffset exists only if ID && MT_CASCADE is non-zero (i.e. if bit b14 in ID is set). If Offset field for an item of icon type is not defined, this is an item with redefinable icons (for example, toolbar menu in Geometry application uses such menu items).

Note that the topmost (b15) bit of field ID is always set, and the topmost bit of field Offset is always clear. It is necessary, because MENY_ENTRY is a variable length structure (4 or 6 bytes), depending on whether a cascade is defined. To correctly move up/down through menu items, TIOS uses the following strategy: on pressing down, if MT_CASCADE is set, move down 6 bytes, otherwise move down 4 bytes. On pressing up, move back 4 bytes, then check bit b15. If it is clear, this is Offset field, so move back another 2 bytes.

All will be more clear through a concrete example. Such variable-sized variable-shape structure like MENU cannot be defined using standard C initializers, but may be defined with help of the built-in assembler. This example defines exactly the same menu like in the example given with PopupDo, but saves about 200 bytes:
#include <menus.h>

int _ti89;

static char menu [] = {};
asm ("menu:
        dc.w   title_text - menu
        dc.w   0xD5
        dc.w   9
        dc.b   0, 40
        dc.w   5
        dc.w   0
        dc.w   0
        dc.w   0
        dc.l   -1
      main_entries:
        dc.w   MT_TEXT + 1                   /* I don't know why | doesn't */
        dc.w   option_1_text - title_text    /* work, so use + instead! */
        dc.w   MT_TEXT + 2
        dc.w   option_2_text - title_text
        dc.w   MT_TEXT + MT_CASCADE + 3
        dc.w   submenu_3_text - title_text
        dc.w   submenu_3_cascade - menu
        dc.w   MT_TEXT + MT_CASCADE + 4
        dc.w   submenu_4_text - title_text
        dc.w   submenu_4_cascade - menu
        dc.w   MT_TEXT + 5
        dc.w   option_5_text - title_text
        dc.l   -1
      submenu_3_cascade:
        dc.w   MT_TEXT + 6
        dc.w   suboption_3_1_text - title_text
        dc.w   MT_TEXT + 7
        dc.w   suboption_3_2_text - title_text
        dc.w   MT_TEXT + 8
        dc.w   suboption_3_3_text - title_text
        dc.l   -1
      submenu_4_cascade:
        dc.w   MT_TEXT + 9
        dc.w   suboption_4_1_text - title_text
        dc.l   -1
      title_text:
        .ascii \"EXAMPLE\"
        dc.b   0
      option_1_text:
        .ascii \"Option 1\"
        dc.b   0
      option_2_text:
        .ascii \"Option 2\"
        dc.b   0
      submenu_3_text:
        .ascii \"Submenu 3\"
        dc.b   0
      submenu_4_text:
        .ascii \"Submenu 4\"
        dc.b   0
      option_5_text:
        .ascii \"Option 5\"
        dc.b   0
      suboption_3_1_text:
        .ascii \"Suboption 3.1\"
        dc.b   0
      suboption_3_2_text:
        .ascii \"Suboption 3.2\"
        dc.b   0
      suboption_3_3_text:
        .ascii \"Suboption 3.3\"
        dc.b   0
      suboption_4_1_text:
        .ascii \"Suboption 4.1\"
        dc.b   0
     ");

void _main (void)
{
  MenuPopup (&menu, CENTER, CENTER, 0);
}
There is an alternative method too. Note that field DynSize (the tenth and eleventh byte) of the MENU structure contains the total length of the structure for dynamically created menus. So, you can make a menu using commands like PopupNew, PopupAddText etc. then to use VTI and the debugger to pick up bytes from the menu structure knowing the length of it. After this, you may pass a pointer to the pre-filled sequence of bytes picked from VTI to this function. I used this approach in the following (cryptic) example which is functionally equivalent to the example given above:
static long menu [] = {0x4800D5, 0x90028, 0x500BA, 0, -1, 0x80010008,
  0x80020012, 0xC003001C, 0x30C004, 0X260040, 0X80050030, -1, 0x8006003A,
  0x80070048, 0x80080056, -1, 0X80090064, -1, 0x4558414D, 0x504C4500,
  0x4F707469, 0x6F6E2031, 0x4F4F70, 0x74696F6E, 0x20320053, 0x5375626D,
  0x656E7520, 0x33005375, 0x626D656E, 0x75203400, 0x4F707469, 0x6F6E2035,
  0x535375, 0x626F7074, 0x696F6E20, 0x332E3100, 0x5375626F, 0x7074696F,
  0x6E20332E, 0x32005375, 0x626F7074, 0x696F6E20, 0x332E3300, 0x5375626F,
  0x7074696F, 0x6E20342E, 0x31000000};
MenuPopup (&menu, CENTER, CENTER, 0);

HANDLE MenuNew (short Flags, short width, short height);

Creates a new toolbar menu.

MenuNew allocates a memory for a new toolbar menu (i.e. menu which looks like the main menu at the home screen), initializes allocated block with necessary structures and returns a handle to it (or H_NULL in a case of error). You can later free the memory by calling HeapFree. width and height are the width and the height of the menu in pixels. The valid range for height is 1-18, and any value out of this range (0, for example) will cause using 18 as the default. Note that using of any other value than 18 seems useless for me, because such menus looks extremely ugly. If the number of the items in the menu is greater than available width of the menu, the menu items will scroll left or right if necessary. This routine may cause the heap compression.

Parameter Flags contains various flags, which are still very unclear to me (they have not any obvious meaning). As TIOS mainly passes Flags = 2 when calling this routine, I also recommend to do so. All I know is that this parameter is copied to the Flags field of the menu structure (see MenuPopup for info about this structure). Any additional info is welcomed.

HANDLE MenuAddText (HANDLE Handle, short Link, char *text, short ret_val, short Flags);

Adds a new text item in a toolbar menu.

MenuAddText adds the text text to the toolbar menu associated with handle Handle. The first added text will be the first option in the menu, the second added text will be the second option, etc. ret_val is the return value which MenuKey function will later return if the user select this menu option. If ret_val is 0, the TIOS will associate the return value automatically (1 to the first menu option, 2 to the second option, etc.). Legal range for ret_val is 1 to 4095. If ret_val is greater than 4095, it will be truncated (ANDed with 0x0FFF). Parameter Link has the following meaning: PopupAddText returns H_NULL in a case of error, else returns Handle. It may cause the heap compression. Although TIOS menu system allows toolbar menus with associated pulldown menus which has its own submenus (i.e. more than one level of nesting), it is not possible to create such menus using this command. If you really want more levels of nesting, you need to use pre-filled static structures and to pass them directly to MenuBegin function (see MenuPopup for more info). But, note that this is somewhat complicated.

Parameter Flags is a mystery. Although it has some meaning (unclear to me) on AMS 2.xx, as far as I know, it has no meaning on AMS 1.xx. When I disasembled this function (on AMS 1.00), the first thing I noticed is that this parameter is ANDed with 0x0004, so if this parameter has any meaning, only sensible values of this parameter are 0 and 4. But, after ANDing, this value is never used in the whole routine. For the moment, I recommended passing 0 to this parameter. Except this additional parameter, there is no any difference between this function and PopupAddText, so it seems that it is possible to add items to toolbar menus with the same functions as with popup menus.

NOTE: On AMS 2.xx, the order of defining menu items and submenu items is important: you need to define all submenu items after defining the main item. You must not, for example, to define first all main menu options, then submenu options.

HANDLE MenuAddIcon (HANDLE Handle, short Link, void *Icon, short ret_val, short Flags);

Adds a new icon item in a toolbar menu.

MenuAddIcon is very similar to MenuAddText, except instead of a text, added menu item will have associtated an icon instead of the text. The icon is a 16x16 bitmap structure given as 16-word group of bits, and parameter Icon is the pointer to it. This pointer is usually of type pICON (pointer to the ICON structure).

NOTE: It seems that it is possible to add items with icons instead of text to popup menus too.

HANDLE MenuBegin (void *MenuPtr, short x, short y, short Flags);

Displays a toolbar menu and creates a new structure which is used for executing the menu.

MenuBegin shows the toolbar menu pointed to by MenuPtr on the screen. The top-left corner of the menu will be at the position (xy), where coordinates are absolute screen coordinates. x, y or both may also have a special value CENTER which means "center the menu on the screen in x, y or both directions". Note that this function does not use the handle: instead, it needs an actual pointer to the menu structure. So, you must use HLock to lock and dereference a handle before using this function (locking is highly recommended because the heap compression may occur):
exec_handle = MenuBegin (HLock (handle), x, y, Flags);
Alternatively (but only if you are an expert), you can pass to MenuBegin a pointer to a pre-filled static menu structure (like TIOS usually does). Using this approach you can save a lot of memory. See MenuPopup for more info about this.

MenuBegin does not activate the menu: you must call MenuKey to activate it. MenuBegin also creates another structure which is necessary to executing the menu, and returns the handle to it (H_NULL in a case of error). This routine may cause heap compression.

Parameter Flags contains various flags. When bit b0 is set, an extra memory space is reserved for the menu, so it allows proper executing of menus which contains icons (i.e. you must set b0 for menus with icons). Bit b1 should be set for menus with redefinable icons (see MenuTopRedef). Bit b2 has some influence to the heap memory management, I don't know exactly what (for now, keep it to zero). This is all what I know about Flags. Any additional info is welcomed.

short MenuKey (HANDLE ExecHandle, short KeyCode);

Activates a toolbar menu.

MenuKey is a heart of any toolbar menus. It activates the menu associated with the handle ExecHandle, where ExecHandle is a handle returned from MenuBegin function (not one returned from MenuNew). Parameter KeyCode is the code of the key associated with the menu item (toolbox) which will be activated. If this toolbox has assigned pulldown menu, it will be opened, then the user can navigate through the menu using arrow keys. If the toolbox has not assigned pulldown menu, MenuKey returns immediately. Typical method of calling MenuKey is passing a result of ngetchx function (which waits for a keypress and return the key code) to the parameter KeyCode:
result = MenuKey (exec_handle, ngetchx ());
MenuKey returns the following result (as far as I know; maybe other return values also exist): If all of this seems complicated to you, here is an example which creates a toolbar menu on the top of the screen with four items (where first and second items have associated pulldown menus), activates it, then frees the memory and restores the default Home screen menu (something like what ToolBar command in TI-Basic does):
handle = MenuNew (2, 240, 18);
MenuAddText (handle, 0, "First", 1, 0);
MenuAddText (handle, 0, "Second", 2, 0);
MenuAddText (handle, -1, "Third", 3, 0);
MenuAddText (handle, -1, "Fourth", 4, 0);
MenuAddText (handle, 1, "Subitem 1.1", 5, 0);
MenuAddText (handle, 1, "Subitem 1.2", 6, 0);
MenuAddText (handle, 2, "Subitem 2.1", 7, 0);
exec_handle = MenuBegin (HLock (handle), 0, 0, 0);
result = -2;
while (result == -2)
   result = MenuKey (exec_handle, ngetchx ());
MenuEnd (exec_handle);
HeapUnlock (handle);
HeapFree (handle);
MenuUpdate ();
Note that this approach is very flexible, because actual reading of the keypress is done in the user program, so it allows various "hooking" into the "heart" of the menu. This routine may cause the heap compression.

void MenuOn (HANDLE ExecHandle);

Redraws a toolbar menu.

MenuOn redraws the menu associated with the handle ExecHandle, where ExecHandle is a handle returned from MenuBegin function. This may be useful after executing functions like MenuTopSelect, etc.

void MenuTopStat (HANDLE ExecHandle, short Item, short State);

Changes the state (active/inactive) of a toolbox.

MenuTopStat changes the state of the toolbox Item (0 = first, 1 = second etc.) which belongs to the menu associated with the handle ExecHandle. ExecHandle is a handle returned from MenuBegin function, not one returned from MenuNew. State is a Boolean value: when it is TRUE, the toolbox will be active, and when it is FALSE, the toolbox will be inactive (i.e. it will be dimmed, and it can not be selected).

MenuTopStat does not force redrawing of the menu in according to the new state; it must be done manually by calling MenuOn.

void MenuSubStat (HANDLE ExecHandle, short ret_val, short State);

Changes the state (active/inactive) of an item in a pulldown menu.

MenuSubStat is very similar to MenuTopStat, but works with items in associated pulldown menus. MenuTopStat changes status of the item which has its ret_val (see MenuAddText) equal to the ret_val which is given as the paramteter of MenuSubStat. See MenuTopStat for more info.

void MenuTopSelect (HANDLE ExecHandle, short Item);

Emphasizes a toolbox.

MenuTopSelect emphasizes (selects) the toolbox Item (0 = first, 1 = second etc.) which belongs to the menu associated with the handle ExecHandle, by drawing a thick border arround the toolbox (Geometry application uses this feature). This command forces redrawing of the menu. Call this function with Item = -1 to cancel the selection. ExecHandle is a handle returned from MenuBegin function, not one returned from MenuNew.

void MenuTopRedef (HANDLE ExecHandle, short Item, unsigned short Index);

Redefines a toolbox icon.

MenuTopRedef redefines the icon in the toolbox Item (0 = first, 1 = second etc.), which belongs to the menu associated with the handle ExecHandle, to the icon with index Index, i.e. to the icon associated with the submenu item which has its ret_val (see MenuAddText) equal to the parameter Index. This is used mainly in Geometry application which has a toolbar menu with redefinable icons. ExecHandle is a handle returned from MenuBegin function, not one returned from MenuNew.

NOTE: As far as I know, such menus can not be created using commands like MenuNew, MenuAddIcon etc. The only way to make a such menu is to create an appropriate pre-filled static menu structure, and to pass a pointer to such structure to MenuBegin. See MenuPopup for more info about menu structures.

unsigned short MenuGetTopRedef (HANDLE ExecHandle, short Item);

Gets the index of a toolbox icon.

MenuGetTopRedef returns the index of the icon in the toolbox Item which belongs to the menu associated with the handle ExecHandle. See MenuTopRedef for more info.

void MenuCheck (HANDLE ExecHandle, short ret_val, short State);

Checks/unchecks an item in a pulldown menu (???).

In according to info presented by Gareth James, MenuCheck checks/unchecks the item in the pulldown submenu which has its ret_val (see MenuAddText) equal to the ret_val which is given as the paramteter of MenuCheck. ExecHandle is a handle returned from MenuBegin function, not one returned from MenuNew. State should be a Boolean value: TRUE for checking and FALSE for unchecking, although value 2 is also considered from some reason. But, note that I didn't succeed to make this function working, I don't know why. Any info is welcomed.

void MenuEnd (HANDLE ExecHandle);

Deallocates an executable menu structure and removes the menu from the screen.

MenuEnd removes the structure needed for executing the toolbar menu (such structure is created using MenuBegin), and removes the menu from the screen by filling menu area with blank pixels. Note that it does not restore the background which was present before the menu is drawn; you must to do it manually. If the menu was drawn on the top of the screen (as usual), calling MenuUpdate may help. Also note that MenuEnd does not remove the structure created using MenuNew; you must call HeapFree to remove it.

void MenuUpdate(void);

Draws the default Home screen menu.

MenuUpdate redraws the default Home screen menu, which often may be useful. More precise, it redraws the menu registered with the current application (for more info, see EV_registerMenu function from events.h header file).


Constants and predefined types


enum Bool

Bool is enumerated type for describing true or false values. It is defined as
enum Bool {FALSE, TRUE};

enum ItemTypes

ItemTypes is enumerated type for describing various item types in menus. It is defined as
enum ItemTypes {MT_TEXT = 0x8000; MT_XREF = 0x9000; MT_ICON = 0xA000;
  MT_CASCADE = 0x4000};
As these constants are used mainly in "asm" statements, they are defined using a special method, so they are visible for the built-in assembler (i.e. in "asm" statements). See the example given with MenuPopup command.

const NULL

NULL is a null-pointer value, defined as (void *) 0.

type HANDLE

HANDLE is a type which represents handles associated to allocated memory blocks. It is defined as
typedef unsigned short HANDLE;

type ICON

ICON is a structure which describes an icon (a 16x16 pixel area), which is used in MenuAddIcon command. It is defined as
typedef struct
  {
    unsigned short i[16];
  } ICON;

type pICON

pICON is a pointer to the ICON scructure. It is defined as
typedef unsigned short *pICON;

const H_NULL

H_NULL is a null-handle defined as a constant with value 0.

const CENTER

When used in PopupDo and MenuBegin commands as the parameter, CENTER means "center the menu on the screen in x, y or both directions", depending of as which parameter CENTER is used. CENTER has in fact value -1.

Return to the main index