home *** CD-ROM | disk | FTP | other *** search
- // Tb26.prg
- //
- // Pull Down menu using TBrowse
- //
- // Compile with /a /m /n /w /dTEST for test version
- //
- // Link with Tbutils, Dict
-
- #include "Inkey.ch"
- #include "Setcurs.ch"
- #include "Tbutils.ch"
-
- #ifdef TEST
- FUNCTION Tb26
-
- LOCAL aPay30Pdown, aCustPdown, aRecPdown, aPayPdown, aMenuPrompts
-
- aPay30Pdown := { ;
- {"By Date", "D", K_ALT_D, {|| Msg("pay_30date")} }, ;
- {"By Company", "C", K_ALT_C, {|| Msg("pay_30comp")} }, ;
- {"Another Menu", "A", K_ALT_A, NIL } ;
- }
-
- aCustPdown := { ;
- {"By Name", "N", K_ALT_N, {|| Msg("cust_byname")} }, ;
- {"By Id.", "I", K_ALT_I, {|| Msg("cust_byid")} }, ;
- {"By City", "C", K_ALT_C, {|| Msg("cust_bycity")} } ;
- }
-
- aRecPdown := { ;
- {"By Inv. Num", "I", K_ALT_I, {|| Msg("rec_byinv")} }, ;
- {"By conTact", "T", K_ALT_T, {|| Msg("rec_bycon")} }, ;
- {"Current", "C", K_ALT_C, {|| Msg("rec_cur")} }, ;
- {"> 30 Days", "3", K_ALT_3, {|| Msg("rec_30")} }, ;
- {"> 60 Days", "6", K_ALT_6, {|| Msg("rec_60")} } ;
- }
-
- aPayPdown := { ;
- {"By comPany", "P", K_ALT_P, {|| Msg("pay_comp")} }, ;
- {"By conTact", "T", K_ALT_T, {|| Msg("pay_cont")} }, ;
- {"Current", "C", K_ALT_C, {|| Msg("pay_cur")} }, ;
- {"> 30 Days", "3", K_ALT_3, aPay30Pdown }, ;
- {"> 60 Days", "6", K_ALT_6, {|| Msg("pay_60")} } ;
- }
-
- aMenuPrompts := { ;
- {"Customers", "C", K_ALT_C, aCustPdown }, ;
- {"receiVables", "V", K_ALT_V, aRecPdown }, ;
- {"paYables", "Y", K_ALT_Y, aPayPdown } ;
- }
- /*
- {"Customers", "C", K_ALT_C, aCustPdown }, ;
- {"receiVables", "V", K_ALT_V, aRecPdown }, ;
- {"paYables", "Y", K_ALT_Y, aPayPdown }, ;
- {"Customers", "C", K_ALT_C, aCustPdown }, ;
- {"receiVables", "V", K_ALT_V, aRecPdown }, ;
- {"paYables", "Y", K_ALT_Y, aPayPdown }, ;
- {"Customers", "C", K_ALT_C, aCustPdown }, ;
- {"receiVables", "V", K_ALT_V, aRecPdown }, ;
- {"paYables", "Y", K_ALT_Y, aPayPdown } ;
- }
- */
- aPay30Pdown[3, 4] := aMenuPrompts
-
- SetCancel(.F.)
- CLEAR SCREEN
- DoMenu(aMenuPrompts)
-
- RETURN NIL
- #endif
-
- #define PROMPT_SPACING 2
- #define LEFT_PROMPT_START 2
- #define PROMPT_ROW 1
-
-
- FUNCTION DoMenu(aMenuPrompts)
-
- LOCAL nTBColumns := Len(aMenuPrompts)
- LOCAL i
- LOCAL oTbc
- LOCAL oTbr := TBrowseNew()
- LOCAL lExitRequested
- LOCAL nKey
- LOCAL cSaveScr := SaveScreen(PROMPT_ROW - 1, 0, PROMPT_ROW + 1, MaxCol())
- LOCAL nSaveCursor := SetCursor(SC_NONE)
- LOCAL nPromptWidths := 0
- LOCAL nPrompt
-
- // Set color to menu colors here ...
-
- @ PROMPT_ROW - 1, 0 CLEAR TO PROMPT_ROW + 1, MaxCol()
- @ PROMPT_ROW - 1, 0 TO PROMPT_ROW + 1, MaxCol()
-
- // Create one TBColumn for each prompt, and calculate
- // combined widths of all prompts
- FOR i := 1 TO nTBColumns
- oTbc := TBColumnNew(, Ablock(aMenuPrompts, i))
- oTbr:addColumn(oTbc)
- nPromptWidths += Len(aMenuPrompts[i, 1])
- NEXT
-
- // Prompts are separated by PROMPT_SPACING characters
- oTbr:colSep := Space(PROMPT_SPACING)
- nPromptWidths += (PROMPT_SPACING * (nTBColumns - 1))
-
- oTbr:nTop := PROMPT_ROW
- oTbr:nLeft := LEFT_PROMPT_START
- oTbr:nBottom := PROMPT_ROW
-
- // We want to left align prompts.
- IF nPromptWidths < (MaxCol() - 1) - LEFT_PROMPT_START
- oTbr:nRight := LEFT_PROMPT_START + nPromptWidths - 1
- ELSE
- oTbr:nRight := MaxCol() - LEFT_PROMPT_START
- ENDIF
-
- // To eliminate the highlight bar
- // oTbr:autoLite := .F.
-
- lExitRequested := .F.
- DO WHILE !lExitRequested
- DrawHorizPrompts(oTbr, aMenuPrompts)
-
- nKey := Inkey(0)
- IF !StdMeth(nKey, oTbr)
- IF (nPrompt := Ascan(aMenuPrompts, ;
- {|aPrompt| aPrompt[3] == nKey})) > 0
- oTbr:deHilite()
-
- oTbr:colPos := nPrompt
- DrawHorizPrompts(oTbr, aMenuPrompts)
- KEYBOARD Chr(K_ENTER)
- ELSE
- DO CASE
- CASE nKey == K_ESC
- lExitRequested := .T.
-
- CASE nKey == K_ENTER
- IF ValType(aMenuPrompts[oTbr:colPos, 4]) == "B"
- Eval(aMenuPrompts[oTbr:ColPos, 4])
- ELSE
- DoPullDown(PROMPT_ROW + 2, Col(), ;
- aMenuPrompts[oTbr:colPos, 4])
- ENDIF
- ENDCASE
- ENDIF
- ENDIF
- ENDDO
- SetCursor(nSaveCursor)
- RestScreen(0, 0, 3, MaxCol())
-
- RETURN NIL
-
-
- FUNCTION Ablock(aMenu, i)
-
- RETURN {|| aMenu[i, 1] }
-
-
- FUNCTION DrawHorizPrompts(oTbr, aMenuPrompts)
-
- LOCAL aColors := ColorSplit(SetColor())
- LOCAL cSaveColor, nSaveRow, nSaveCol, nHotCharOffset, i, aCols
-
- DispBegin()
- FullStabilize(oTbr)
-
- // Get column positions of each visible column
- aCols := TbcColPos(oTbr)
-
- // Redisplay HOT character in selected color
- cSaveColor := SetColor(aColors[2])
- nSaveRow := Row()
- nSaveCol := Col()
- FOR i := oTbr:leftVisible TO oTbr:rightVisible
- nHotCharOffset := At(aMenuPrompts[i, 2], aMenuPrompts[i, 1])
- IF nHotCharOffset > 0
- @ PROMPT_ROW, aCols[i] + nHotCharOffset - 1 SAY aMenuPrompts[i, 2]
- ENDIF
- NEXT
- @ nSaveRow, nSaveCol SAY ""
- SetColor(cSaveColor)
- DispEnd()
-
- RETURN NIL
-
-
- #define MAX_PULL_DOWN_HEIGHT 6
-
- FUNCTION DoPullDown(nRow, nCol, aMenuPrompts)
-
- LOCAL nPrompts
- LOCAL oTbr := TBrowseNew()
- LOCAL oTbc
- LOCAL nPromptsWidth := 0
- LOCAL nMenuHeight
- LOCAL cSaveScr
- LOCAL nSaveRow := Row()
- LOCAL nSaveCol := Col()
- LOCAL lExitRequested
- LOCAL nKey
- LOCAL aFirstLast := Array(2)
- LOCAL nPrompt
-
- nPrompts := Len(aMenuPrompts)
-
- // Find widest prompt
- Aeval(aMenuPrompts, ;
- {|aPrompt| nPromptsWidth := Max(nPromptsWidth, Len(aPrompt[1])) })
-
- oTbr:nTop := nRow + 1
- oTbr:nLeft := nCol + 1
-
- nMenuHeight := Min(nPrompts, MAX_PULL_DOWN_HEIGHT)
- oTbr:nBottom := nRow + 1 + nMenuHeight - 1
-
- oTbr:nRight := nCol + 1 + nPromptsWidth - 1
-
- oTbr:cargo := 1
- oTbr:goTopBlock := {|| oTbr:cargo := 1 }
- oTbr:goBottomBlock := {|| oTbr:cargo := Len(aMenuPrompts) }
- oTbr:skipBlock := ARRAY_SKIPPER(oTbr:cargo, aMenuPrompts)
-
- // Adjust in case nBottom > MaxRow() - 1
- IF oTbr:nBottom > MaxRow() - 1
- oTbr:nBottom := MaxRow() - 1
- oTbr:nTop := oTbr:nBottom - nMenuHeight + 1
- ENDIF
-
- // Adjust in case nRight > MaxCol() - 1
- IF oTbr:nRight > MaxCol() - 1
- oTbr:nRight := MaxCol() - 1
- oTbr:nLeft := oTbr:nRight - nPromptsWidth + 1
- ENDIF
-
- oTbc := TBColumnNew(, {|| aMenuPrompts[oTbr:cargo, 1]} )
- oTbc:width := oTbr:nRight - oTbr:nLeft + 1
- oTbr:addColumn(oTbc)
-
- cSaveScr := SaveScreen(oTbr:nTop - 1, oTbr:nLeft - 1, ;
- oTbr:nBottom + 1, oTbr:nRight + 1)
- @ oTbr:nTop - 1, oTbr:nLeft - 1 CLEAR TO oTbr:nBottom + 1, oTbr:nRight + 1
- @ oTbr:nTop - 1, oTbr:nLeft - 1 TO oTbr:nBottom + 1, oTbr:nRight + 1
- lExitRequested := .F.
- DO WHILE !lExitRequested
- DrawVertPrompts(oTbr, aMenuPrompts)
- nKey := Inkey(0)
- IF !StdMeth(nKey, oTbr)
- aFirstLast = GetFirstLast(oTbr)
- IF (nPrompt := Ascan(aMenuPrompts, ;
- {|aPrompt| aPrompt[3] == nKey})) > 0
- IF nPrompt >= aFirstLast[1] .OR. nPrompt <= aFirstLast[2]
- oTbr:deHilite()
- oTbr:rowPos := nPrompt - aFirstLast[1] + 1
- ELSE
- oTbr:cargo := nPrompt
- oTbr:refreshAll()
- ENDIF
- DrawVertPrompts(oTbr, aMenuPrompts)
- KEYBOARD Chr(K_ENTER)
- ELSE
- DO CASE
- CASE nKey == K_ESC
- lExitRequested := .T.
-
- CASE nKey == K_ENTER
- IF ValType(aMenuPrompts[oTbr:cargo, 4]) == "B"
- Eval(aMenuPrompts[oTbr:cargo, 4])
- ELSE
- DoPullDown(Row() + 1, ;
- Col() + Int(2 * (nPromptsWidth / 3)), ;
- aMenuPrompts[oTbr:cargo, 4])
- ENDIF
- ENDCASE
- ENDIF
- ENDIF
- ENDDO
-
- RestScreen(oTbr:nTop - 1, oTbr:nLeft - 1, ;
- oTbr:nBottom + 1, oTbr:nRight + 1, cSaveScr)
- @ nSaveRow, nSaveCol SAY ""
-
- RETURN NIL
-
-
- FUNCTION DrawVertPrompts(oTbr, aMenuPrompts)
-
- LOCAL aColors := ColorSplit(SetColor())
- LOCAL nHotCharOffset
- LOCAL cSaveColor
- LOCAL nSaveRow, nSaveCol
- LOCAL i
- LOCAL aFirstLast := Array(2)
-
- nSaveRow := Row()
- nSaveCol := Col()
-
- FullStabilize(oTbr)
- aFirstLast := GetFirstLast(oTbr)
-
- DispBegin()
- cSaveColor := SetColor(aColors[2])
-
- FOR i := 1 TO aFirstLast[2] - aFirstLast[1] + 1
- nHotCharOffset := At(aMenuPrompts[i + aFirstLast[1] - 1, 2], ;
- aMenuPrompts[i + aFirstLast[1] - 1, 1])
- IF nHotCharOffset > 0
- @ oTbr:nTop + i - 1, ;
- oTbr:nLeft + nHotCharOffset - 1 ;
- SAY aMenuPrompts[i + aFirstLast[1] - 1, 2]
- ENDIF
-
- NEXT
-
- SetColor(cSaveColor)
- @ nSaveRow, nSaveCol SAY ""
- DispEnd()
-
- RETURN NIL
-
-
- // Get the array indexes of the first and last prompts
-
- FUNCTION GetFirstLast(oTbr)
-
- LOCAL aFirstLast := Array(2)
- LOCAL nSaveCurrent
- LOCAL lSaveAutoLite
-
- nSaveCurrent := oTbr:rowPos
- lSaveAutoLite := oTbr:autoLite
-
- DispBegin()
-
- oTbr:autoLite := .F.
- oTbr:deHilite()
-
- oTbr:rowPos := 1
- FullStabilize(oTbr)
- aFirstLast[1] := oTbr:cargo
-
- oTbr:rowPos := oTbr:rowCount
- FullStabilize(oTbr)
- aFirstLast[2] := oTbr:cargo
-
- oTbr:rowPos := nSaveCurrent
- oTbr:autoLite := lSaveAutoLite
- FullStabilize(oTbr)
-
- DispEnd()
-
- RETURN aFirstLast
-
-
- FUNCTION ColorSplit(cColorToSplit)
-
- LOCAL nColorNum, nNextComma, aColors[5]
-
- FOR nColorNum := 1 TO 4
- nNextComma := At(",", cColorToSplit)
- aColors[nColorNum] := Substr(cColorToSplit, 1, nNextComma - 1)
- cColorToSplit := Substr(cColorToSplit, nNextComma + 1)
- NEXT
-
- aColors[5] = cColorToSplit
-
- RETURN aColors
-
-
- FUNCTION Msg(cMess)
-
- LOCAL cSaveScr := SaveScreen(MaxRow(), 0, MaxRow(), MaxCol())
- LOCAL nSaveRow := Row()
- LOCAL nSaveCol := Col()
-
- @ MaxRow(), 0
- @ MAxRow(), 0 SAY cMess
- InKey(0)
- RestScreen(MaxRow(), 0, MaxRow(), MaxCol(), cSaveScr)
- @ nSaveRow, nSaveCol SAY ""
-
- RETURN NIL