저도 옛 기억을 되살려 하드디스크를 좀 찾아봤습니다.
풀다운 메뉴를 만드는 라이브러리가 있더군요.
아마도, 16년 전 쯤에 작성했던것으로 기억이 나는군요.
세월 참.. 많이 지났습니다.
#include "achoice.ch"
#include "inkey.ch"
static aChoices := {}, nHpos, nVpos, nMaxRow, nMaxCol, lSubMenu
func PullDown( aBar, aOptions, nTopRow, lShadow )
local nTtlWid, nTtlUsed, i, j, nPad
local sMainScrn, lCancMode, lLooping := .t.
local nSaveCur, alSelectable, nKey
local aBarCol[len(aBar)]
local aBarWidth[len(aBar)]
local aBoxLoc[len(aBar)]
local aLastSel[len(aBar)]
local aColors := { 'w/n', 'n/w', 'w+/n' }
nMaxRow := maxrow()
nMaxCol := maxcol()
nTopRow := if( nTopRow == NIL, 0, nTopRow )
lSubMenu := .t.
nSaveCur := setCursor(0)
afill(aLastSel,1)
aChoices := aOptions
nTtlWid := 0
aBarCol[1] := 1
nTtlUsed := len(aBar[1])+1
aeval( aBar ,;
{|x,i| aBarcol[i] := nTtlUsed,;
nTtlUsed += (len(aBar[i]))} ,;
2, len(aBar) - 1 )
afill( aBarWidth,1 )
aeval( aChoices, { |x,i| _ftWidest( @i, aChoices, @aBarWidth ) } )
aeval( aChoices, { |x,i| _ftLocat( i, aBarCol, aBarWidth, @aBoxLoc, nMaxCol ) } )
setcolor( aColors[2] )
@ 0, 0 say space(MaxCol()+1)
devpos( nTopRow, 0 )
aeval( aBar, { |x,i| Devpos(nTopRow, aBarCol[i]), Devout(aBar[i]) })
save screen to sMainScrn
nHpos := 1
nVpos := 1
while lLooping
restore screen from sMainScrn
@ nTopRow, aBarCol[nHpos] say aBar[nHpos] color aColors[1]
if lSubMenu
setColor(aColors[1])
DispBox( nTopRow+1, aBoxLoc[nHpos], len(aChoices[nHpos,1])+nTopRow+2, aBarWidth[nHpos]+1+aBoxLoc[nHpos], '' )
setcolor( aColors[1] +","+ aColors[2] +",,"+aColors[3]+","+ aColors[1] )
alSelectable := {}
for i := 1 to len(aChoices[nHpos,3])
aadd( alSelectable, eval(aChoices[nHpos,3,i] ) )
next
nVpos := achoice( nTopRow+2, aBoxLoc[nHpos]+1, len(aChoices[nHpos,1])+nTopRow+2, aBarWidth[nHpos]+aBoxLoc[nHpos], aChoices[nHpos,1], alSelectable, "_ftAcUdf", aLastSel[nHpos])
nKey := lastkey()
else
nKey := ft_sinkey(0)
end
do case
case nKey == K_RIGHT
if lSubMenu
aLastSel[nHpos] := nVpos
end
if( nHpos == len( aChoices ), nHpos := 1, nHpos := nHpos + 1 )
case nKey == K_LEFT
if lSubMenu
aLastSel[nHpos] := nVpos
end
if( nHpos == 1, nHpos := len( aChoices ), nHpos := nHpos - 1 )
case nKey == K_DOWN
if !lSubMenu
lSubMenu := .t.
end
case nKey == K_ESC
if lSubMenu
aLastSel[nHpos] := nVpos
lSubMenu := .f.
else
exit
end
case nKey == K_ENTER
if lSubMenu
aLastSel[nHpos] := nVpos
if aChoices[nHpos,2,nVpos] != NIL
lLooping := eval( aChoices[nHpos,2,nVpos] )
end
else
lSubMenu := .t.
end
endcase
end
setCursor(nSaveCur)
return NIL
function _ftAcUdf( nMode )
local nRtnVal := AC_CONT
do case
case nMode == AC_HITTOP
keyboard chr( K_CTRL_PGDN )
case nMode == AC_HITBOTTOM
keyboard chr( K_CTRL_PGUP )
case nMode == AC_EXCEPT
nRtnVal := AC_SELECT
endcase
return nRtnVal
static proc _ftWidest( i, aChoices, aBarWidth )
aeval( aChoices[i,1] ,;
{ |a,b| aBarWidth[i] := ;
max( aBarWidth[i],len(aChoices[i,1,b])) } )
return
static proc _ftLocat( i, aBarCol, aBarWidth, aBoxLoc, nMaxCol )
aBoxLoc[i] := if( aBarCol[i] + aBarWidth[i] + 4 > nMaxCol + 1, ;
nMaxCol - 4 - aBarWidth[i], aBarCol[i] )
return
proc FillMenu( aArray, cMenuOption, bExcute, bAvailable )
aadd( aArray[1], cMenuOption )
aadd( aArray[2], bExcute )
aadd( aArray[3], bAvailable )
return
// eof
|