Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- Grumpfish Library 3.2 - <b>apick()</b> http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
APICK()

   APICK() makes displaying ACHOICE() menus easier.  First, it handles
   the mundane chores, such as drawing the box outline and restoring the
   screen afterwards.  But APICK() really shines in those instances when
   there are more options than will fit in the box. It adds an
   "elevator" status bar, with an indicator that shows where you are
   relative to the first and last (top and bottom) array elements.
   Plus, when there are more options above the top or bottom of the box,
   an up or down arrow will be displayed to indicate this fact.

   But wait, there's more!  You may also do additive searches by typing
   in the first few letters of a desired option.  You can also give the
   users the ability to tag and toggle multiple array items for batch
   processing.

   APICK() also makes it very easy for you to specify which array
   elements will be selectable and unselectable.  You may also direct it
   to draw horizontal lines within the menu for aesthetic purposes.

   Syntax

   APICK(<top>, <left>, <bottom>, <right>, <array> [,<box color>, ;
         <elevator bar color>, <indicator color>, <actual elements>, ;
         <tagging>, <unselected color>, <highlight color>, <minit>, ;
         <selected color>, <unavailable color>, <title>, <wrapping>, ;
         <boxtype>, <movedown>]

   Parameters shown in bold apply only to the Clipper 5.0 version.
   (See below for the syntax of the APICK user-defined command.)

   Required Parameters

   <top>, <left>, <bottom>, <right> are integers representing the
   coordinates of the box to be drawn. (Note: in the 5.0 version, these
   parameters are optional -- if they are not passed, APICK() will
   automatically center the box on the screen.)

   <array> is a character string representing the name of the array that
   holds the choices.

   Optional Parameters

   <box color> is a character string representing the color with which
   to draw the box.  The default is white on blue (white on black for
   monochrome monitors).  You may pass a null string if you want to use
   the default.

   <elevator bar color> is a character string representing the color
   with which to draw the status bar.  The default is white on black.
   You may pass a null string if you want to use the default.

   <indicator color> is a character string representing the color with
   which to draw the indicator on the status bar.  The default is yellow
   (white for monochrome).  You may pass a null string if you want to
   use the default. If you do change the color, to prevent confusion I
   recommend that you use something other than the box color and the
   highlighted element color.

   <actual elements> is a numeric expression representing the actual
   number of elements to use.  The only reason you would ever want to
   use this parameter is in the event that you have declared an array of
   a certain length, then deleted elements from it.  For an example of
   where this is required, look no further than the Grumpfish Library
   notepad. When you want to edit a new file, an array is filled
   containing all of the filenames in the target directory.  All
   inappropriate filenames (.EXE, .COM, .DBF, etc) are then deleted.

   Suppose that the array initially contained 50 files, and 30 of them
   were deleted.  If you do not pass 20 as the <actual elements>
   parameter, your status bar will never go all the way to the bottom.

   The <tagging> parameter takes on two forms dependent on what
   version of Clipper you are using.  In the Summer '87 APICK(), it is
   a logical flag that determines whether or not your users will be
   able to tag and toggle array items as selected.  The default is
   tagging OFF.  If you want to use tagging, this is an example of how
   you can check the array after APICK() to see what elements were
   tagged:

   ** summer '87 syntax                                              
   sel = APICK(9, 34, 16, 46, myarray, '', '', '', len(myarray), .t.)
                                                                     
   for x = 1 to len(myarray)                                         
      if chr(251) $ myarray[x]                                       
         ** this item is selected!                                   
      endif                                                          
   next                                                              

   In the Clipper 5.0 APICK(), <tagging> is a character string representing
   the name of an array.  This array will be manipulated within APICK()
   so that you can determine which elements were tagged.  Although Clipper
   5.0 does allow functions to return arrays, I chose to implement this
   because this construction allows you to "pre-tag" items prior to
   calling APICK().  Also, I felt it was bad programming form to have
   this function potentially return two different data types (array if
   tagging, numeric if not).

   The tag array must be initialized prior to calling APICK(), but you
   do not need to fill it with any elements.  APICK() will do that
   automatically for you.

   The following code demonstrates the 5.0 syntax for APICK() tagging.
   It shows how you would manipulate the tag array, as well as how
   you can use the tag array to pre-tag items.  Note that this code
   uses the APICK user-defined command from the GRUMP.CH header file.

   #include "grump.ch"                                     
   #include "inkey.ch"                                     
                                                           
   function main                                           
   local x, a := directory(), tags := {}, mainloop := .t.  
   //-----  convert directory() array from nested to simple
   for x := 1 to len(a)                                    
      a[x] := a[x][1]   // only keep filename (1st element)
   next                                                    
   do while mainloop                                       
      apick x array a tagging tags     // UDC from GRUMP.CH
      cls                                                  
      ? "You tagged the following files:"                  
      ?                                                    
      for x := 1 to len(tags)                              
         if tags[x]                                        
            ? a[x]                                         
         endif                                             
      next                                                 
      ? "Press ESC to exit, any other key to tag again..." 
      mainloop := (inkey(0) != K_ESC)                      
   enddo                                                   
   return nil                                              

   <unselected color> is a character string representing the color in
   which to display such unavailable choices.  Pass a null string if
   you don't need this.  The default is white on blue (white on black
   for monochrome).

   <highlight color> is a character string representing the color to
   use for the highlight bar.  Pass a null string if you do not need
   this. The default is inverse.

   <minit> is a numeric expression representing the initial element to
   be highlighted.  Refer to the Clipper manual discussion of ACHOICE()
   if you need more info on this.

   <title> is a character string that will be displayed, centered, on
   the top row of the APICK box.  By default, there will be no title.

   Additional 5.0 Optional Parameters

   <selected color> is a character string representing the color in
   which to display choices that have been tagged.  The default is
   "+GR/B, +W/R" for color monitors, and "+W/N, N/W" for monochrome.

   <unavailable color> is a character string representing the color in
   which to display choices that are unavailable for selection.  The
   default is "R/B, N/B" for color monitors, and "+W/N, N/W" for
   monochrome.

   <wrapping> is a logical value that determines whether the user should
   be allowed to "wrap" from the top element to the bottom with up arrow
   (or from the bottom to the top via down arrow).  By default, wrapping
   will be enabled.  To override it, pass false (.F.) as the last
   parameter.  (NOTE: applies to Clipper 5.0 version only!) If you are
   using the APICK user-defined command (see below), then just specify
   the NOWRAP clause.

   <boxtype> is a numeric indicating which type of box outline to use
   for the APICK() window.  This corresponds directly to the box types
   used with the ShadowBox() function (1 = double, 2 = single, etc).
   By default, a double-line box will be used.

   <movedown> is a logical that determines whether or not to move down a
   row after tagging an element.  By default, this will be on.  If you
   do not desire this wonderful behavior, either pass .F. as the 19th
   parameter, or if you are saving time and energy with the APICK
   user-defined command (see below), use the NOMOVE optional clause.
   Note that <movedown> is significant only when you have enabled
   tagging.

   Return Value

   APICK() returns an integer representing the option selected.  If Esc
   is pressed to terminate the ACHOICE(), it will return zero.

   Notes

   Elevator Bar

   As you scroll up and down through the window, the indicator will move
   up and down on the status bar, showing you where you are relative to
   the first and last option.  If there are more options above the first
   element shown in the window, an up arrow will be displayed at the
   upper right corner of the box.  If there are more options below the
   last element shown, a down arrow will be drawn at the lower right
   corner of the box.

   Wrapping

   ACHOICE() has no inherent provision for wrapping when you press up
   arrow at the top item, or down arrow at the bottom item.
   Fortunately, it is simple to tweak APICK() to handle this.  We take
   advantage of the fact that ACHOICE() is kind enough to designate
   special status codes in the event that we attempt to move past the
   top or bottom of the array.

   In the Clipper 5.0 version, you may override this by passing false
   (.F.) as the <wrapping> parameter, or by specifying the NOWRAP
   clause in conjunction with the user-defined command.

   Tagging multiple array elements

   APICK() gives the user the ability to tag any or all items by
   highlighting an item and pressing the space bar. But why stop there?
   Let's give them something to remember! If the user presses F8, they
   will tag all items in the array.  If they press F9, they will untag
   everything. Pressing F10 will toggle each tag to the opposite of what
   it was; i.e., if item 1 was tagged and item 2 was not tagged, after
   pressing F10 item 1 will not untagged and item 2 will be tagged.

   Selectable vs. Unselectable

   With ACHOICE(), you generally have to pass a parallel logical array
   to instruct ACHOICE() as to which items are selectable.  However,
   this grew tiresome for me, so I thought of a different method to use.
   If an item in the array was to be unselectable, simply precede it
   with a tilde ("~").

   An array is declared within APICK() and initialized to True (all
   items selectable).  Then we loop through the array.  If any items
   begin with a tilde, we change the appropriate element of the array to
   False.  Of course, this means that we have to get rid of the tilde
   before we display the array for selection, but that's no big deal.

   You can also have horizontal lines for aesthetic purposes by having
   array elements contain a tilde and the character to use for the line.
   For example, "~-" will be expanded into a horizontal line that
   will encompass the width of the ACHOICE() box.

   array[1] = "Available"              
   array[2] = "Available"              
   array[3] = "Available"              
   array[4] = "~"    && horizontal line
   array[5] = "Available"              
   array[6] = "~Not Available"         
   array[7] = "~Not Available"         

   Additive Search

   When you press a letter key, ACHOICE() jumps to the next array
   element that begins with that letter.  However, in the grand scheme
   of things this is not particularly useful.  The ability to type in
   the entire element (or at least enough to uniquely identify it) is
   always preferable.  That is the least we can give to our harried
   user.

   As with the status bar, we must prepare beforehand, though not quite
   as stringently.  We declare a variable SEARCHSTR and initialize it to
   a null string.  This will contain the value to search the array for.

   Meanwhile, back in the UDF, we test for a letter key press.If one is
   detected, we add it to SEARCHSTR and search the array for it by
   calling ASCAN(). ASCAN() returns a numeric value which represents the
   first find. If it is unable to find the desired value, it returns
   zero.

   Therefore, if ASCAN() returns a non-zero value, we know that our
   array contains the search value, and we change the current element to
   the element where it was found.  We also display the contents of
   SEARCHSTR (up to the first six characters, which should be
   sufficient) centered on the bottom row of the box for easy reference.

   Sample Usage

   PRIVATE choices[8], sel                             
   choices[1] = '~Unavailable'                         
   choices[2] = 'Unwilling'                            
   choices[3] = 'Unable'                               
   choices[4] = 'Un-Cola'                              
   choices[5] = '~-'          && horizontal line       
   choices[5] = 'Underwater'                           
   choices[6] = 'Unctious'                             
   choices[7] = 'Uncle'                                
   choices[8] = 'Underwear'                            
   sel = APICK(10, 34, 15, 46, choices)                
   sel2 = APICK(10, 34, 15, 46, choices,'W/R', '', 'G')

   Clipper 5.0 Notes

   - If you wish to skip parameters, just include the commas and do
     not pass null strings.
   - ACHOICE() has been replaced by TBROWSE().
   - Clipper 5.0 lets us pass a code block as the value to search for.
     This allows us to perform a case-insensitive search:

     ASCAN(array, { | a | UPPER(a) = UPPER(value) } )

   - The GRUMP.CH header file includes an APICK user-defined command,
     which makes it easier for you to use APICK().  Note that if you
     wish to use this, you must #include GRUMP.CH at the top of your
     program.

     Syntax

     APICK [<var>] ARRAY <array> [TOP <top>] [LEFT <left>]               ;
        [BOTTOM <bottom>] [RIGHT <right>] [BOXCOLOR <boxcolor>]          ;
        [BARCOLOR <barcolor>] [STATCOLOR <statcolor>] [LENGTH <length>]  ;
        [TAGGING] [UNSELECTED <unsel>] [HIGHLIGHT <highlight>]           ;
        [INITIAL <initial>] [SELECTED <selected>] [UNAVAILABLE <unava>]  ;
        [TITLE <title>] [NOWRAP] [BOXTYPE <box>] [NOMOVE]

     These parameters are exactly the same as listed above, with the
     exception of <var>.  <var> is the name of the variable in which to
     store the APICK() return value.  Note that <var> is an optional
     clause -- this is because you should not need to use it in conjunction
     with tagging.

     The big advantage to using the user-defined command is that you can
     use optional clauses in any order that you desire.  This means that
     you no longer have to remember the exact order of all the
     parameters (and there are quite a few!).

See Also: SHADOWBOX()

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