Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- Force 4.0 Reference - menupulldown() execute a pulldown menu system http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 menupulldown()      Execute a pulldown menu system
------------------------------------------------------------------------------
 Declaration
   menu.hdr

 Syntax
   func logical menupulldown extern
   param value _MENU pMenu

 Arguments
   pMenu is the pointer to a previously created menu system. If 0, the
         default menu will be used.

 Return
   A logical indicating the success of this function - if .f., an invalid
   menu pointer was passed.

 Description
   This function executes a nested pull-down menu system with a horizontal
   main menu, and vertical sub-menus. Sub-menus can be framed according to
   the mode set via the menupdframe() function, and the horizontal main menu
   may either just occupy as much space as is required to display the
   prompts, or it may cover the full screen width, depending on the mode set
   via the menupdfull() function.

   The defaults are: "full", and "no frame".

 Example
   #define EXAMPLE_MENU
   #include example.hdr

   // Defines for the prompt Id's of the main menu, and for the pMenu[] array
   // indices.
   
   #define MNU_MAIN     0
   #define MNU_FILE     1
   #define MNU_EDIT     2
   #define MNU_VIEW     3
   #define MNU_OPTIONS  4
   #define MNU_HELP     5
   
   // Defines for the prompt Id's of the sub-menus.
   
   // File menu Id's
   //
   #define FILE_NEW     1
   #define FILE_OPEN    2
   #define FILE_SAVE    3
   #define FILE_SAVE_AS 4
   #define FILE_PRINT   5
   #define FILE_QUIT    6
   
   // File - Save as sub-sub-menu Id's
   //
   #define SAVE_AS_ASC  1
   #define SAVE_AS_BIN  2
   
   // Edit menu Id's
   //
   #define EDIT_CUT     1
   #define EDIT_COPY    2
   #define EDIT_PASTE   3
   #define EDIT_SEEK    4
   #define EDIT_NEXT    5
   
   // View menu Id's
   //
   #define VIEW_TABLE   1
   #define VIEW_RECORD  2
   
   // Options menu Id's
   //
   #define OPT_SORT     1
   #define OPT_COLOR    2
   #define OPT_PRINT    3
   #define OPT_SCREEN   4
   
   // Help menu Id's
   //
   #define HLP_MANUAL   1
   #define HLP_ABOUT    2
   
   // This array holds the menu root pointers
   //
   //   pMenu[0]            holds the main menu pointer,
   //   pMenu[1]...pMenu[5] hold the sub-menu pointers
   //
   // Note that the indices to the elements holding the sub-menus are
   // identical to their Id's in the main menu.
   //
   vardef
      _MENU pMenu[6]
   enddef
   
   // The sub-menu "executor" functions.
   //
   // NOTE: In a "real live application", the procedures will call or execute
   //       additional code which handles the various operations.
   //       Here, we only activate and de-activate some prompt items (except
   //       for the FILE_PRINT prompt, where we perform a little delay to
   //       simulate printing).
   //
   // The function return value controls if the associated sub-menu shall be
   // closed (.f.), or not (.t.).
   //
   func logical FileFunc
   param value _MENU pMenu, value uint nId
   
   vardef
      logical lRet
   enddef
   
   lRet := .f.
   
   do case
   case nId == FILE_NEW
      menusetactive( pMenu, FILE_SAVE,    .t., .t. )
      menusetactive( pMenu, FILE_SAVE_AS, .t., .t. )
      menusetactive( pMenu, FILE_PRINT,   .t., .t. )
      menusetactive( pMenu, FILE_NEW,     .f., .t. )
      menusetactive( pMenu, FILE_OPEN,    .f., .t. )
   case nId == FILE_OPEN
      menusetactive( pMenu, FILE_SAVE,    .t., .t. )
      menusetactive( pMenu, FILE_SAVE_AS, .t., .t. )
      menusetactive( pMenu, FILE_PRINT,   .t., .t. )
      menusetactive( pMenu, FILE_NEW,     .f., .t. )
      menusetactive( pMenu, FILE_OPEN,    .f., .t. )
   case nId == FILE_SAVE
      menusetactive( pMenu, FILE_NEW,     .t., .t. )
      menusetactive( pMenu, FILE_OPEN,    .t., .t. )
      menusetactive( pMenu, FILE_SAVE,    .f., .t. )
      menusetactive( pMenu, FILE_SAVE_AS, .f., .t. )
      menusetactive( pMenu, FILE_PRINT,   .f., .t. )
   case nId == FILE_SAVE_AS
      menusetactive( pMenu, FILE_NEW,     .t., .t. )
      menusetactive( pMenu, FILE_OPEN,    .t., .t. )
      menusetactive( pMenu, FILE_SAVE,    .f., .t. )
      menusetactive( pMenu, FILE_SAVE_AS, .f., .t. )
      menusetactive( pMenu, FILE_PRINT,   .f., .t. )
   case nId == FILE_PRINT
      @ 15, 2 ?? "printing..."
      ticks(30)
      @ 15, 2 ?? "           "
      lRet := .t.
   
   // Here, we "fake" an Esc key to quit the program from the main menu
   //
   case nId == FILE_QUIT
      keyint( K_ESC )
   
   endcase
   
   return lRet
   endpro
   
   func logical EditFunc
   param value _MENU pMenu, value uint nId
   
   do case
   case nId == EDIT_CUT
      menusetactive( pMenu, EDIT_PASTE, .t., .t. )
   case nId == EDIT_COPY
      menusetactive( pMenu, EDIT_PASTE, .t., .t. )
   case nId == EDIT_PASTE
   
   case nId == EDIT_SEEK
      menusetactive( pMenu, EDIT_NEXT, .t., .t. )
   case nId == EDIT_NEXT
   endcase
   
   return .f.
   endpro
   
   func logical ViewFunc
   param value _MENU pMenu, value uint nId
   do case
   
   // Note that the order of calls to menusetactive() is important here.
   // As this sub-menu only has two items, it is important to first acti-
   // vate an item, and them de-activate the other item because de-acti-
   // vating an item automatically makes the next or previous item current.
   //
   // If you would de-activate one of the two items first, there would be
   // no active item at all, i.e. no item could be set current.
   //
   case nId == VIEW_TABLE
      menusetactive( pMenu, VIEW_RECORD, .t., .t. )
      menusetactive( pMenu, VIEW_TABLE,  .f., .t. )
   case nId == VIEW_RECORD
      menusetactive( pMenu, VIEW_TABLE,  .t., .t. )
      menusetactive( pMenu, VIEW_RECORD, .f., .t. )
   endcase
   return .f.
   
   endpro
   
   func logical OptFunc
   param value _MENU pMenu, value uint nId
   return .f.
   endpro
   
   func logical HelpFunc
   param value _MENU pMenu, value uint nId
   return .f.
   endpro
   
   // This is the "executor" for the "File" - "Save as..." sub-sub-menu.
   //
   // Note that it changes the active status of items in the "parent menu".
   func logical SaveAsFunc
   param value _MENU pxMenu, value uint nId
   
   menusetactive( pMenu[MNU_FILE], FILE_NEW,     .t., .t. )
   menusetactive( pMenu[MNU_FILE], FILE_OPEN,    .t., .t. )
   menusetactive( pMenu[MNU_FILE], FILE_SAVE,    .f., .t. )
   menusetactive( pMenu[MNU_FILE], FILE_SAVE_AS, .f., .t. )
   menusetactive( pMenu[MNU_FILE], FILE_PRINT,   .f., .t. )
   
   return .f.
   endpro
   
   proc Test_menupulldown
   vardef
      uint    i
      _MENU pSubSub
   enddef
   
   // Turn on hot keys.
   //
   menusethot( .t. )
   
   clear
   @  3, 0 ?? "Menu demo with nested pull-down menus."
   @  5, 0 ?? "To see how nested menus work, select 'File' - 'New', and then"
   @  6, 0 ?? "'File' - 'Save as...' for another sub-menu."
   @  7, 0 ?? "Also note how certain prompts get active, and non-active,"
   @  8, 0 ?? "depending on your selections."
   @  9, 0 ?? "Select 'File' - 'Quit' to end the demo."
   
   /*
     Structure of the menu system
   
     File       Edit        View      Options       Help
     |          |           |         |             |
     |-New      |-Cut       |-Table   |-Sort order  |-On-line manual
     |          |           |         |             |
     |-Open     |-Copy      +-Record  |-Colors      +-About
     |          |                     |
     |-Save     |-Paste               |-Printer
     |          |                     |
     |-Save as  |-Find                +-Screen size
     | |        |
     | |-ASCII  +-Find next
     | |
     | +-Binary
     |
     +-Quit
   */
   
   // Here come the definitions for the menu system
   
   // This is the main menu
   //
   // As usual, we first install a menu root...
   //
   pMenu[MNU_MAIN] := MenuNew()
   
   // ...then add the prompts
   //
   menupromptnew( pMenu[MNU_MAIN], 0,  0, " File ",    MNU_FILE,    .t., .f.)
   menupromptnew( pMenu[MNU_MAIN], 0,  6, " Edit ",    MNU_EDIT,    .t., .f.)
   menupromptnew( pMenu[MNU_MAIN], 0, 12, " View ",    MNU_VIEW,    .t., .f.)
   menupromptnew( pMenu[MNU_MAIN], 0, 18, " Options ", MNU_OPTIONS, .t., .f.)
   menupromptnew( pMenu[MNU_MAIN], 0, 27, " Help ",    MNU_HELP,    .t., .f.)
   
   // Now comes the first sub-menu
   //
   // We install the sub-menu root...
   //
   pMenu[MNU_FILE] := MenuNew()
   
   // ... define the screen offset...
   //
   menusetoffset( pMenu[MNU_FILE], 1, 0 )
   
   // ... add the prompts...
   //
   menupromptnew( pMenu[MNU_FILE], 0, 0, " New        ",  ;
                  FILE_NEW,     .t., .f. )
   menupromptnew( pMenu[MNU_FILE], 1, 0, " Open       ",  ;
                  FILE_OPEN,    .t., .f. )
   menupromptnew( pMenu[MNU_FILE], 2, 0, " Save       ",  ;
                  FILE_SAVE,    .f., .f. )
   menupromptnew( pMenu[MNU_FILE], 3, 0, " Sa&ve as... ", ;
                  FILE_SAVE_AS, .f., .f. )
   menupromptnew( pMenu[MNU_FILE], 4, 0, "------------",  ;
                  0,            .f., .f. )
   menupromptnew( pMenu[MNU_FILE], 5, 0, " Print      ",  ;
                  FILE_PRINT,   .f., .f. )
   menupromptnew( pMenu[MNU_FILE], 6, 0, "------------",  ;
                  0,            .f., .f. )
   menupromptnew( pMenu[MNU_FILE], 7, 0, " Quit       ",  ;
                  FILE_QUIT,    .t., .f. )
   
   // ... and assign the "executor" function(s).
   //
   for i := FILE_NEW to FILE_QUIT
      menusetfunc( pMenu[MNU_FILE], i, &FileFunc )
   next
   
   // We now link the File sub-menu with the File prompt in the main menu.
   //
   //          +----------------------------The target menu
   //          |                +-----------The promt item in the target menu
   //          |                |         +-The sub-menu to be linked
   //          |                |         |
   menusetsub( pMenu[MNU_MAIN], MNU_FILE, pMenu[MNU_FILE] )
   
   // Here we define a sub-sub-menu
   //
   // The menu root
   //
   pSubSub := menunew()
   
   // The screen offset
   //
   menusetoffset( pSubSub, 4, 12 )
   
   // The prompts
   //
   menupromptnew( pSubSub, 0, 0, " ASCII  ",  SAVE_AS_ASC, .t., .f. )
   menupromptnew( pSubSub, 1, 0, " Binary ",  SAVE_AS_BIN, .t., .f. )
   
   // The "executor" function
   //
   for i := 1 to 2
      menusetfunc( pSubSub, i, &SaveAsFunc )
   next
   
   // This menu is a sub-menu linked to the "File" sub-menu's "Save as..."
   // prompt.
   //
   menusetsub( pMenu[MNU_FILE], FILE_SAVE_AS, pSubSub )
   
   // Same as above for the remaining sub-menus
   //
   // Edit
   //
   pMenu[MNU_EDIT] := MenuNew()
   menusetoffset( pMenu[MNU_EDIT], 1, 6 )
   menupromptnew( pMenu[MNU_EDIT], 0, 0, " Cut       ", EDIT_CUT,   .t., .f.)
   menupromptnew( pMenu[MNU_EDIT], 1, 0, " Copy      ", EDIT_COPY,  .t., .f.)
   menupromptnew( pMenu[MNU_EDIT], 2, 0, " Paste     ", EDIT_PASTE, .f., .f.)
   menupromptnew( pMenu[MNU_EDIT], 3, 0, "-----------", 0,          .f., .f.)
   menupromptnew( pMenu[MNU_EDIT], 4, 0, " Seek...   ", EDIT_SEEK,  .t., .f.)
   menupromptnew( pMenu[MNU_EDIT], 5, 0, " Find next ", EDIT_NEXT,  .f., .f.)
   for i := EDIT_CUT to EDIT_NEXT
      menusetfunc( pMenu[MNU_EDIT], i, &EditFunc )
   next
   menusetsub( pMenu[MNU_MAIN], MNU_EDIT, pMenu[MNU_EDIT] )
   
   // View
   //
   pMenu[MNU_VIEW] := MenuNew()
   menusetoffset( pMenu[MNU_VIEW], 1, 12 )
   menupromptnew( pMenu[MNU_VIEW], 0, 0, " Table  ", VIEW_TABLE,  .t., .f. )
   menupromptnew( pMenu[MNU_VIEW], 1, 0, " Record ", VIEW_RECORD, .f., .f. )
   for i := VIEW_TABLE to VIEW_RECORD
      menusetfunc( pMenu[MNU_VIEW], i, &ViewFunc )
   next
   menusetsub( pMenu[MNU_MAIN], MNU_VIEW, pMenu[MNU_VIEW] )
   
   // Options
   //
   pMenu[MNU_OPTIONS] := MenuNew()
   menusetoffset( pMenu[MNU_OPTIONS], 1, 18 )
   menupromptnew( pMenu[MNU_OPTIONS], 0, 0, " Sort order  ", ;
                  OPT_SORT,   .t., .f. )
   menupromptnew( pMenu[MNU_OPTIONS], 1, 0, " Colors      ", ;
                  OPT_COLOR,  .t., .f. )
   menupromptnew( pMenu[MNU_OPTIONS], 2, 0, " Printer     ", ;
                  OPT_PRINT,  .t., .f. )
   menupromptnew( pMenu[MNU_OPTIONS], 3, 0, " Screen size ", ;
                  OPT_SCREEN, .t., .f. )
   
   for i := OPT_SORT to OPT_SCREEN
      menusetfunc( pMenu[MNU_OPTIONS], i, &OptFunc )
   next
   menusetsub( pMenu[MNU_MAIN], MNU_OPTIONS, pMenu[MNU_OPTIONS] )
   
   // Help
   //
   pMenu[MNU_HELP] := MenuNew()
   menusetoffset( pMenu[MNU_HELP], 1, 27 )
   menupromptnew( pMenu[MNU_HELP], 0, 0, " On-line manual ", ;
                  HLP_MANUAL, .t., .f. )
   menupromptnew( pMenu[MNU_HELP], 1, 0, " About          ", ;
                  HLP_ABOUT,  .t., .f. )
   
   for i := HLP_MANUAL to HLP_ABOUT
      menusetfunc( pMenu[MNU_HELP], i, &HelpFunc )
   next
   menusetsub( pMenu[MNU_MAIN], MNU_HELP, pMenu[MNU_HELP] )
   
   cursor( .f. )
   
   menusetcurrent( pMenu[MNU_MAIN], MNU_FILE )
   
   menupdframe( PD_FRAME_NONE )
   
   menupulldown( pMenu[MNU_MAIN] )
   
   // This clears all the menus from memory
   //
   menuclear( pMenu[MNU_MAIN] )
   
   @ 22, 0
   
   endproc

   proc main
   Test_menupulldown()
   endproc

See Also: menupdframe() menupdfull()

Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson