FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Generic function to show an array and select one item
Posts: 28
Joined: Tue Nov 15, 2005 01:03 AM
Generic function to show an array and select one item
Posted: Sun Jan 07, 2007 01:15 PM
Hi guys

In the FW spanish forum I left a generic function to show an array and return the item number optionally

Although other similar functions have been published, this one allows:

1. To show the full either partial array
2. To show the columns ordered by user criterion
3. Set columns header, size and justify
4. Set grid colors
5. To show browse in the chosen position and with provided dimensions
6. To make incremental search by anyone of the columns
7. To order in run time any column
8. To return the element selected position in the array when pressing ENTER or to make double click

In order to avoid the use of auxiliary functions I have based the work on codeblocks, this way can be but simple its implementation. The function must be called with the following parameters:

    ShowTable( aTable, cTitle, aSize, aCoord, aCols, aCargo, bColor )[/list:u]
    donde:
      aTable= Array to process
      cTitle = Dialog title
      aSize = Browse size (in pixels)
      aCoord = Dialog position
      aCols = Columns array. Each one with 5 parameters. Example:
        Position in the array(N)
        Column Title (C)
        Column Size (N)
        Column Justify (N)
        Column Picture (N)
        Active Column (L) (To shadow the active column)[/list:u][/list:u]
        Example
        	aArray := { 
        	            { "Peter", "Memphis", 5.21 }, ;
        	            { "Bob", "N.Y.", 6.1 },       ;
        	            { "Florida", 3.5 },           ;
        	            {  "Alabama", 2.5 }           ;
        	          }
        	nPos   := ShowTable( aArray,                           ;
        		                 "Pick a Salesman",                ;
        		                 { 190, 115 },                     ;
        		                 { 170, 16 },                      ;
        		                 { {  1, "Name", 100, 0 },         ;
        		                   {  3, "Fee",  70, 0, '99.99' }, ;
        		                   {  2, "State",  70, 0 }         ;
        			             }  )

        the function admits character, dates or numeric type elements and transform them for their correct visualization into browse. In case of numerical elements it is necessary to indicate the picture

        I want to indicate that the Selcolor function that appears in the ShowTable function its a generic function of odd / even painted rows and it can be omitted. It comes from some examples published in this forum

        I hope this work can be useful
        /*********************************************************************************************
              ShowTable()     : Show an array and select one item optionally
        *********************************************************************************************/
        function ShowTable( aTable, cTitle, aSize, aCoord, aCols, aCargo, bColor )
        
        	local oDlg, oLbx, oSay, vSay, aData, n, m, oFont[1], nRetVal := 0
        	local aColSize, aJustify, aRecord, aAction, nActiveCol := 0
        
        	default aCargo := { 0 }
        	bColor := if( bColor = nil, { || SelColor( oLbx:nAt, 2 ) }, &( bColor ) )
        
        	default aSize  := { 160, 115 }
        	default aCoord := { oCfg:nRow+85, oCfg:nCol }
        
        	if ValType( aTable ) == "A"
        		define font oFont[1] name "Tahoma" size 0,-12
        		define dialog oDlg title cTitle font oFont[1]
        		oDlg:lHelpIcon := .F.
        		
        		aData    := {}
        		aColSize := {}
        		aHeader  := {}
        		aJustify := {}
        		aAction  := {}
        		for n := 1 to Len( aTable )
        			aRecord := {}
        			for m := 1 to Len( aCols )
        				AADD( aRecord, if( ValType( aTable[n,aCols[m,1]] ) = "D", DtoC( aTable[n,aCols[m,1]] ),                  ;
        				               if( ValType( aTable[n,aCols[m,1]] ) = "N", Transform( aTable[n,aCols[m,1]], aCols[m,5] ), ;
        				                   aTable[n,aCols[m,1]] )) )
        				if n = 1
        					AADD( aHeader,  aCols[m,2] )
        					AADD( aColSize, aCols[m,3] )
        					AADD( aJustify, aCols[m,4] )
        					AADD( aAction,  { |Self, nRow, nCol| nLbxCol := oLbx:nAtCol(nCol),                                       ;
        					                                     if( oLbx:cargo[1] <> nLbxCol,                                       ;
        					                                         ( cSearch := "", vSay := Space(200), oSay:Refresh(),            ;
        					                                           aData := ASort( aData,,, { |x,y| x[nLbxCol] < y[nLbxCol] } ), ;
        					                                           oLbx:nColHPressed := nLbxCol, oLbx:cargo[1] := nLbxCol,       ;
        					                                           oLbx:Refresh() ),                                             ;
        					                                          nil ) } )
        					nActiveCol := if( Len(aCols[m]) >= 5 .and. aCols[m,5], m, nActiveCol )
        				endif
        			next
        			AADD( aRecord, Str(n,4) )
        			AADD( aData, AClone( aRecord ) )
        		next
        		
        		// I add one column to the right to control the original order
        		AADD( aHeader,  "No." )
        		AADD( aColSize, 10 )
        		AADD( aJustify, 1 )
        		AADD( aAction, { nil } )
        		
        		vSay := ""
        		@ aSize[2]+3, 5 say oSay var vSay of oDlg size 100,12 pixel
        		
        		oLbx := TWBrowse():New( 0, 0, aSize[1], aSize[2],,,,,,,,,,,,,,,,,,.t.,,,,, )
        		LbxConfig( oLbx )
        		oLbx:SetArray( aData )
        		oLbx:bLine := { |nAt| nAt := oLbx:nAt,                              ;
        		                      if( Len( aData ) < 1 .or. nAt > Len( aData ), ;
        			                      Array(6),                                 ;
        				                  aData[nAt] ) }
        		oLbx:aHeaders       := aHeader
        		oLbx:aColSizes      := aColSize
        		oLbx:aJustify       := aJustify
        		oLbx:aActions       := aAction
        		oLbx:bUpdateBuffer  := { || oLbx:cBuffer := Upper(oLbx:cBuffer),                                                       ;
        		                            vSay := if( Len(oLbx:cBuffer) > 0, PadR( "Buscando: " + oLbx:cBuffer, 200 ), Space(200) ), ;
        		                            oSay:Refresh()                                                                             ;
        		                       }
        		oLbx:bSeek          := { || if( oLbx:cargo[1] = 0,                                                                      ;
        		                                MsgStop( 'Haga clic en el titulo de la columna' + CRLF +                                ;
        		                                         'por la que desea buscar', 'Atención' ),                                       ;
        		                                ( cSearch := Upper( oLbx:cBuffer ),                                                     ;
        		                                  nLen := Len( cSearch ),                                                               ;
        		                                  vSay := if( Len(cSearch) > 0, PadR( "Buscando: " + cSearch, 200 ), Space(200) ),      ;
        		                                  oSay:Refresh(),                                                                       ;
        		                                  nCol := oLbx:cargo[1],                                                                ;
        		                                  if( nLen > 0,                                                                         ;
        		                                      ( nAt := AScan( aData, { |x,y| Upper( SubStr( x[nCol], 1, nLen )) == cSearch } ), ;
        		                                        if( nAt > 0,                                                                    ;
        		                                            ( oLbx:nAt := nAt,                                                          ;
        		                                              if( oLbx:oVScroll != nil,  oLbx:oVScroll:SetPos(nAt), nil ),              ;
        		                                              oLbx:Refresh() ),                                                         ;
        		                                            nil )),                                                                     ;
        		                                      nil )) ) }
        		oLbx:nBuffer        := 10
        		oLbx:lAutoEdit      := .f.
        		oLbx:lAutoSkip      := .f.
        		oLbx:lAdjLastCol    := .t.
        		oLbx:cargo          := { nActiveCol }
        		oLbx:nHeaderHeight  := 18
        		oLbx:nLineStyle     := 1
        		oLbx:nClrLine       := nRGB( 200, 200, 215 )
        		oLbx:lDrawFocusRect := .f.
        		oLbx:nClrPane       := bColor
        		oLbx:nClrLine       := nRGB( 200, 200, 215 )
        		oLbx:nClrBackHead   := nRGB( 215, 215, 215 )
        		oLbx:nClrForeHead   := nRGB(   0,   0,   0 )
        		oLbx:nClrForeFocus  := nRGB( 255, 255, 255 )
        		oLbx:nClrBackFocus  := nRGB(   0,   0,   0 )
        		oLbx:nClrNFFore     := nRGB(   0,   0,   0 )
        		oLbx:nClrNFBack     := nRGB( 180, 180, 180 )
        		oLbx:bBkColor       := { |nRow,nCol,nStyle| if( nCol = oLbx:cargo[1] .and. ( nStyle = 0 .or. nStyle = 1 ), ;
        		                                                oCfg:aLbxColors[2],                                        ;
        		                                                nil ) }
        		
        		oLbx:bKeyDown       := { | nKey | if( nKey == VK_RETURN,                               ;
        		                                      (  nAt     := oLbx:nAt,                          ;
        		                                         nRetVal := Val( aData[nAt,Len(aData[nAt])] ), ;
        		                                         oDlg:End() ),                                 ;
        		                                      nil ) }
        		
        		oLbx:bLDblClick     := { | nKey | nRetVal := oLbx:nAt, oDlg:End() }
        
        		activate dialog oDlg on init ( oDlg:SetSize( oLbx:nWidth+8, oLbx:nHeight+60 ), ;
        									   oDlg:Move( aCoord[1],aCoord[2]),                ;
        									   oDlg:Update() )
        		AEval( oFont, {|o| o:End() } )
        	endif
        
        return nRetVal

         ===================================================================================================
        //         SelColor()  : Configura las filas del grid en bi-color
        // ===================================================================================================
        function SelColor( nVal, nColor, cAlias, cColor ) 
            local nClr, nIndex
        
            if cAlias <> nil
                if !Empty( (cAlias)->( OrdBagName() ) )
        			nIndex := (cAlias)->( OrdKeyNo() ) % 2
                else
                    nIndex := (cAlias)->( RecNo() ) % 2
                endif
            else
                nIndex := if( nVal == nil, 0, nVal % 2 )
            endif
        
            if nIndex = 0
                do case
                case nColor == 1
                    nClr := oCfg:aLbxColors[1]
                case ncolor == 2
                    nClr := oCfg:aLbxColors[2]
                case nColor == 3
                    nClr := RGB(238,238,238)               //   RGB( 163, 202, 197 )
                case nColor == 4
                    nClr := RGB( 160, 160, 128 )
                case nColor == 5
                    nClr := RGB( 245, 235, 195 )
                case nColor == 0
                    nClr := ColorName( AllTrim( cColor ))
                endcase
            else 
                nClr := CLR_WHITE
            endif 
        
        return nClr

Continue the discussion