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 - pickdisp() display a string list with enhanced features http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 pickdisp()          Display a string list with enhanced features
------------------------------------------------------------------------------
 Declaration
   pick.hdr

 Syntax
   func uint pickdisp extern
   param value _SLIST pList, ;
         value int    iTop, ;
         value int    iLeft, ;
         value int    iBottom, ;
         value int    iRight

 Arguments
   pList is a list pointer.
   iTop is the top row for the display.
   iLeft is the leftmost column for the display.
   iBottom is the bottom row for the display.
   iRight is the rightmost column for the display.

 Return
   The list item selected by pressing the Enter key or a unique item hot key,
   or 0 if the function is terminated by pressing the Escape key or by the
   PDC_QUIT method.

 Description
   The pickdisp() function displays a string list created using the
   pickinit() and pickadd() functions.

   The pickdisp() function offers enhanced functionality over the picklist()
   function:

   . Optional cursor wrap, i.e. the selection bar automatically jumps
     to the first/last item when the user tries to move it past/beyond the
     last/first item in the list.

   . Optional hot-keys, i.e. list items can have one character marked as
     hot-key. In the list, the hot-keys are displayed with a special color
     attribute. The user can then select an item by typing the hot-key.

   . Items can be marked by a leading or trailing "tick mark", e.g. the '.'
     character.

   . Items can be set inactive. Such items are displayed with a special
     color attribute. Optionally, the selection bar can skip inactive items.

   . Optional separator lines can be inserted between items. The selection
     bar automatically skips such lines.

   . The function can be customized by adding a user-defined keystroke
     handler function.

   . The function only expects five parameters, and assumes the most
     commonly required features as defaults. The defaults can be overridden
     by calling functions to change the defaults, where some of these
     defaults can even be changed while the function executes.

   . The function is re-entrant, i.e. while pickdisp() executes, it is
     possible to call other instances of the function without interfering
     the existing instances, and each instance can have its own, different
     defaults.

   . Similar to menu to and get/read, you can specifiy an id number for each
     list item (via the pickaddid() procedure). In this case, pickdisp()
     returns the item's id number instead of the item order number.

   If the pickadd() function was used to fill the list with items, the items'
   id numbers are determined by the order of how they were added to the
   list, i.e. the first item has id 1, the second id 2, etc., and all
   items count, no matter if they are active, non-active or separators.

   If the pickaddid() function was used to fill the list with items,
   the items' id numbers are determined by the value you have passed to
   the pickaddid() procedure in its uId parameter.

   The list display has the following defaults if pickdisp() is called "as is

   Hot-key marker character:  '&'
   Separator line character:  '-'  ( chr(196) )
   Marker character:          '.'                            *
   Marker position:           right                          *
   Wrap mode:                 off                            *
   Skip inactive items:       on                             *
   Keyboard-handler:          internal handler (see below)

   * May be changed by a user-defined keyboard handler while pickdisp()
   executes. If necessary, this handler must take care of refreshing
   he item display.

   The default keyboard handler of the pickdisp() function accepts the
   following keystrokes:

   . Unique hot-key (i.e. there is just one item in the list with that
     hot-key): Select item, terminate and return item id.

   . Non-unique hot-key (i.e. there are two or more items in the list
     with the same hot-key): Move selection bar on the next item in the
     list with the matching hot-key. Hot-keys are not case-sensitive.

   . Enter (K_ENTER): Select the current item, terminate and return item
     id.

   . Esc (K_ESC): Terminate and return 0.

   . Up arrow (K_UP): Move selection bar to the previous item. If
     wrap mode is on, and the selection bar is located on the first
     item in the list, move the selection bar to the last item.
     Scrolls the list if necessary.

   . Down arrow (K_DOWN): Move selection bar to the next item. If
     wrap mode is on, and the selection bar is located on the last
     item in the list, move the selection bar to the first item.
     Scrolls the list if necessary.

   . PgUp (K_PG_UP): If the selection bar is not at the top row, position
     it there, else scroll items by one window towards the first item.
     If the first item is at the window top, do nothing, independent of
     the wrap mode status.

   . PgDn (K_PG_DOWN): If the selection bar is not at the bottom row,
     position it there, else scroll items by one window towards the last
     item. If the last item is at the window bottom, do nothing,
     independent of the wrap mode status.

   . Home (K_HOME): Display the first list item at the window top, and
     position the selection bar there.

   . End (K_END): Display the last list item at the window bottom, and
     position the selection bar there.

   pickdisp() displays the various items in different colors, depending
   on the values contained in the __syscolor[] array:

   . Active un-selected items:

       Text:            __syscolor[ STD ]
       Hot-key:         __syscolor[ UNSEL_CH ]

   . Inactive un-selected items:

       Text:            __syscolor[ INACT ]
       Hot-key:         __syscolor[ INACT ]

   . Active selected items:

       Text:            __syscolor[ ENHCD ]
       Hot-key:         __syscolor[ SEL_CH ]

   . Inactive selected items:

       Text:            __syscolor[ INACT_SEL ]
       Hot-key:         __syscolor[ INACT_SEL ]

   . Separator lines:   __syscolor[ STD ]

   . Marker characters: __syscolor[ STD ]

   The coordinate parameters determine the screen area used for the list
   display. Items which are wider than the screen area will be
   right-truncated. If there are more items in the list than can be
   displayed in the area, items will automatically scroll up and down as
   necessary. The pickdisp() function does not automatically save the screen
   area it uses, nor does it draw a frame around this area.

 Example
   #define EXAMPLE_LIST
   #include example.hdr

   vardef static
      logical   lExitUnique := .t.
      char( 8 ) cLastTime   := ""
   enddef
   
   function uint SubList
   vardef
      _SLIST pSub
      uint   uRet
   enddef
   
   pSub := pickinit()
   picksetwrap( pSub, .f. )
   
   pickadd( pSub, "Item &1" )
   pickadd( pSub, "Item &2" )
   pickadd( pSub, "Item &3" )
   pickadd( pSub, "Item &4" )
   pickadd( pSub, "Item &5" )
   pickadd( pSub, "Item &6" )
   pickadd( pSub, "Item &7" )
   pickadd( pSub, "Item &8" )
   pickadd( pSub, "Item &9" )
   
   savearea( 4, 31, 11, 38 )
   @ 4, 31 to 11, 38
   @ 5, 32 clear to 10, 37
   
   uRet := pickdisp( pSub, 5, 32, 10, 37 )
   
   pickclear( pSub )
   restorearea()
   return uRet
   endproc
   
   function uint MyPickHandler
   param value _SLIST pList, ;      // Pick handle
         value uint   nStatus,  ;      // Status
               uint   nCurrEle         // Current element 1...
   // Modified pickdisp keyboard handler
   vardef
      uint nCh
   enddef
   
   if cLastTime != Time()
      cLastTime := Time()
      @ 2, 22 ?? cLastTime
   endif
   
   @ 2, 46 ?? pickid( pList, nCurrEle ):2
   @ 2, 64 ?? nCurrEle:2
   
   nCh := PDC_IDLE
   
   do case
   
   case nStatus == PDS_FOUND_ONE
      if lExitUnique
         nCh := PDC_RETURN
      endif
   
   case nStatus == PDS_INIT
      nCh := PDC_HOME
   
   otherwise
      nCh := inkey()
   
      do case
   
      // We use'Enter' here to select an item and to finish
      //
      case nCh == K_ENTER .and. PickIsActive(pList, nCurrEle)
         nCh := PDC_RETURN
   
      // We use F1 to toggle wrapping here
      //
      case nCh == K_F1
         if pickiswrap( pList )
            picksetwrap( pList, SL_WRAP_OFF )
            @ 16, 16 ?? "on "
         else
            picksetwrap( pList, SL_WRAP_ON )
            @ 16, 16 ?? "off"
         endif
         nCh := PDC_IDLE
   
      case nCh == K_F2
         nCh := PDC_IDLE
         if pickisskip( pList )
            picksetskip( pList, SL_SKIP_OFF )
            @ 17, 16 ?? "on "
         else
            picksetskip( pList, SL_SKIP_ON )
            @ 17, 16 ?? "off"
            if .not. PickIsActive( pList, nCurrEle )
               nCh := PDC_DOWN
            endif
         endif
   
      case nCh == K_F3
         lExitUnique := .not. lExitUnique
         if lExitUnique
            @ 18, 11 ?? "Don't exit on unique hot-keys"
         else
            @ 18, 11 ?? "Exit on unique hot-keys      "
         endif
   
      case nCh == K_F4
         nCurrEle := SubList()
         nCh := PDC_GOTO
   
      case nCh == K_F5
         picksetmarkpos( pList, .not. pickmarkpos( pList ) )
         nCh := PDC_REFRESH_ALL
         if pickmarkpos( pList )
            @ 20, 11 ?? "Right aligned markers"
         else
            @ 20, 11 ?? "Left aligned markers "
         endif
   
      // We use 'Space' to toggle an item marker
      //
      case nCh == ' '
         picksetact( pList, nCurrEle, .t. )
         PickSetMarked( pList, nCurrEle, ;
                        .not. PickIsMarked( pList, nCurrEle ) )
         nCh := PDC_REFRESH_LINE
   
      // We use 'Ins' to toggle the active flag of an item
      //
      case nCh == K_INS
         picksetact( pList, nCurrEle, ;
                     .not. PickIsActive( pList, nCurrEle ) )
         if .not. PickIsActive( pList, nCurrEle )
            PickSetMarked( pList, nCurrEle, .f. )
         endif
         nCh := PDC_REFRESH_LINE
   
      // The usual stuff follows...
      //
      case nCh == K_ESC
         nCh := PDC_QUIT
   
      case nCh == K_UP
         nCh := PDC_UP
   
      case nCh == K_DOWN
         nCh := PDC_DOWN
   
      case nCh == K_PG_UP
         nCh := PDC_PG_UP
   
      case nCh == K_PG_DOWN
         nCh := PDC_PG_DOWN
   
      case nCh == K_HOME
         nCh := PDC_HOME
   
      case nCh == K_END
         nCh := PDC_END
   
      case ( nCh > ' ' ) .and. ( nCh < 255 )
         nCurrEle := nCh
         nCh := PDC_HOT
   
      endcase
   endcase
   return nCh
   endfunc
   
   proc Test_pickdisp
   vardef
      _SLIST pList
      int    iRes, c
   enddef
   
   __syscolor[ CLR_STD ]       := BLUE_WHITE
   __syscolor[ CLR_INACT ]     := BLUE_LIGHT_GREY
   __syscolor[ CLR_INACT_SEL ] := GREEN_LIGHT_GREY
   __syscolor[ CLR_ENHCD ]     := GREEN_BLACK
   __syscolor[ CLR_UNSEL_CH ]  := BLUE_LIGHT_RED
   __syscolor[ CLR_SEL_CH ]    := GREEN_RED
   
   clear
   pList := pickinit()
   
   pickaddid( pList, "&One",                           2 )
   pickaddid( pList, "T&wo",                           4 )
   pickaddid( pList, "Th&ree",                         6 )
   pickaddid( pList, "-",                              0 )
   pickaddid( pList, "Fo&ur",                          8 )
   pickaddid( pList, "Fiv&e",                         10 )
   pickaddid( pList, "&Six is a very long string...", 12 )
   pickaddid( pList, "S&even",                        14 )
   pickaddid( pList, "Ei&ght",                        16 )
   
   picksetudf( pList, &MyPickHandler )
   
   picksetskip( pList, SL_SKIP_OFF )
   
   picksetmarked( pList, 3, .t. )
   picksetact( pList, 5, .f. )
   
   @ 4, 2 to 11, 29
   
   @  2,  3 ?? "pickdisp() Test"
   @  2, 32 ?? "Current Id:"
   @  2, 50 ?? "Current Item:"
   @ 13,  3 ?? "Enter = Select"
   @ 14,  3 ?? "Space = Toggle mark"
   @ 15,  3 ?? "Ins   = Toggle select"
   @ 16,  3 ?? "F1    = Wrap off"
   @ 17,  3 ?? "F2    = Skip on "
   @ 18,  3 ?? "F3    = Don't exit on unique hot-keys"
   @ 19,  3 ?? "F4    = Another pickdisp()"
   @ 20,  3 ?? "F5    = Right aligned markers"
   @ 21,  3 ?? "Esc   = Quit"
   
   iRes := pickdisp( pList, 5, 3, 10, 28 )
   
   @ 4, 31 ?? "Results:"
   @ 6, 33 ?? "Selected Id:  ", iRes:3
   @ 7, 33 ?? "Selected Item:", pickseekid( pList, iRes ):3
   @ 8, 33 ?? "Item text:      ", ;
      pickstring( pList, pickseekid( pList, iRes ) )
   @ 9, 33 ?? "Marked Items:"
   c := 50
   for iRes := 1 to pickcount( pList )
      if pickismarked( pList, iRes )
         @ 9, c ?? iRes:1
         c += 2
      endif
   next
   
   @ 10, 33 ?? "Active Items:"
   c := 50
   for iRes := 1 to pickcount( pList )
      if pickisactive( pList, iRes ) .and. ;
         ( pickstr( pList, iRes ) != chr( picklinech( pList ) ) )
         @ 10, c ?? iRes:1
         c += 2
      endif
   next
   @ 22, 0
   pickclear( pList )
   endproc

   proc main
   Test_pickdisp()
   endproc

See Also: List display table pickkeystd() picksetudf()

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