Pequena adaptação na função ylib_mainMenu para aceitar voltar o menu com <ESC>. Para funcionar é necessário baixar o pacote anterior e substituir a referida função em ylib.prg. Foram corrigidos alguns pequenos bugs e também foram acrescentados recursos para navegação com menu aberto em nÃvel 1 se não houverem menus horizontais desabilitados. Vejam:
[img]
http://i.picasion.com/pic78/073ca31b5cf ... 9ded8d.gif[/img]
O Código:
/**
--------------------------------------------------------------------------------------------------------------------
Descrição:
[007] Cria um Menu Completo (Horizontal + Vertical MultinÃvel)
Parâmetros:
1. l1...........: Linha inicial do Menu
2. c1...........: Coluna inicial do Menu
3. opcoes.......: Matriz com opções e mensagens de status do Menu, opção habilitado/desabilitado, deslocamento(linha e coluna do menu)
4. corMenu......: Cor do menu padrão e selecionado
5. espacamento..: Espaçamento entre os menus
6. lstatus......: linha de mensagem de status
7. cormenudesabilitado.: cor do menu que estiver desabilitado
8. tipoSombra...: pode ser 0, 1, 2, 3, 4, respectivamente, sem sombra, sombra na posição inferior esquerdo, inferior direito, superior esquerdo e superior direito
9. corsombra....: cor da sombra (padrao n+/n)
--------------------------------------------------------------------------------------------------------------------
*/
function ylib_mainMenu(l1,c1,opcoes,corMenu,espacamento,lstatus,corMenuDesabilitado,tipoSombra,corSombra)
local contador := 0, ct:=0, opc:= 0, mHorizontal:={}, mVertical:={}, ct2, tela, ret:="", telaTotal, maxMenu := 0,;
tagSubmenu := " " + chr(226) + chr(150) + chr(182) + " ", escolhaOpcao:=array(5), tam, tamMenu:=array(4), nivel,;
tela1, tela2, tela3, tela4
private navega:=0
save screen to telaTotal
nivel := 0 // variavel para controlar o retorno do menu via <ESC>
do while.t.
if nivel <> 0 // controla a posicao dos menus quando voltamos com esc
marca := .t.
else
marca:=.f.
endif
navega:=0
if nivel == 0 // nivel inicial - Menu Horizontal
restore screen from telaTotal
// reiniciando os gerenciadores de retorno e os vetores temporários...
ret:=""
mHorizontal:={}
mVertical:={}
// Pegando os menus horizontais:
for ct:= 1 to len(opcoes)
if ylib_len(alltrim(opcoes[ct][1])) <> 0
aadd(mHorizontal,{opcoes[ct][1],opcoes[ct][2],opcoes[ct][3]})
endif
next
opcoesHorizontais := len(mHorizontal) // total de opcoes do menu horizontal...
opc := ylib_criaMenu(l1,c1,mHorizontal,corMenu,espacamento,lstatus,corMenuDesabilitado)
escolhaopcao[1] = opc // guarda o menu escolhido
ret := alltrim(str(opc)) // gerencia o retorno da função
if opc == 0
exit
endif
nivel := 1 // nivel é igual a um
endif // fim do nivel = 0 - inicial menu horizontal
// gerenciando o menu vertical de nÃvel 1 =====================================================================
// Pegando os menus verticais
if nivel <= 1
contador := 0
for ct2:= 1 to len(opcoes)
if ylib_len(alltrim(opcoes[ct2][1])) <> 0
++ contador
endif
// verificando a opção escolhida
if contador == escolhaopcao[1]
if ylib_len(alltrim(opcoes[ct2][1])) == 0
if ylib_len(alltrim(opcoes[ct2][2])) <> 0
aadd(mVertical,{opcoes[ct2][2],opcoes[ct2][3],opcoes[ct2][4]})
else
if !(tagSubmenu $ mVertical[len(mVertical)][1])
mVertical[len(mVertical)][1] += tagSubmenu // verificando submenus vinculados
endif
endif
endif
endif
next
// Verificando a posição do Menu Vertical
xc1 = c1
for ct:= 2 to escolhaopcao[1]
xc1 += ylib_len(mHorizontal[ct][1]) + espacamento
if ct==escolhaopcao[1]
exit
endif
next
tamMenu[1] :=0 // tamanho menu
for ct:=1 to len(mVertical)
tamMenu[1]:=max(tamMenu[1],ylib_len(mVertical[ct][1]))
next
tamMenu[1]:=tamMenu[1]+4
save screen to tela1
set key 4 to ylib_avancarMenuHorizontal()
set key 19 to ylib_voltarMenuHorizontal()
opc := ylib_criaMenuVertical(l1+1,xc1,mVertical,corMenu,lstatus,corMenuDesabilitado,tiposombra,corSombra)
escolhaopcao[2] = opc // guarda o menu escolhido
set key 4 to
set key 19 to
if lastkey() == 27 .and. navega==1
keyboard replicate(chr(4),escolhaopcao[1])+chr(13)
nivel := 0
loop
endif
if lastkey() == 27 .and. navega==2
keyboard replicate(chr(4),escolhaopcao[1]-1)+replicate(chr(19),1)+chr(13)
nivel := 0
loop
endif
ret += "."+alltrim(str(opc)) // gerencia o retorno da função
// Verificando a opção escolhida (excluindo separadores de menu)
contador := 0
for ct:= 1 to len(mVertical)
if (alltrim(mVertical[ct][1]) <> "-")
++contador
endif
if opc == contador
verifica := mVertical[ct][1]
exit
endif
next
if opc == 0 // tecla ESC
restore screen from tela1
nivel := 0 // retorna para o nivel 0 inicial
loop
else
if !(tagSubmenu $ verifica) // se não tem um submenu cai fora
exit
endif
endif
nivel := 2
endif // fim nivel = 1
// gerenciando o menu vertical de nÃvel 2 =====================================================================
// Pegando os menus verticais
if nivel <= 2 // nivel 2 do menu
if marca =.f.
mverticalOLD:= mVertical
endif
mVertical := {}
contador := 0
for ct2:= 1 to len(opcoes)
if ylib_len(alltrim(opcoes[ct2][1])) <> 0
++ contador
endif
// verificando a opção escolhida
if contador == escolhaopcao[1]
ct:= ct2
exit
endif
next
contador:=0
for ct2:= (ct+1) to len(opcoes)
if ylib_len(alltrim(opcoes[ct2][2])) <> 0 .and. alltrim(opcoes[ct2][2]) <> "-"
++ contador
endif
// verificando a opção escolhida
if contador == escolhaopcao[2]
if ct2 > len(opcoes) // Verifica o estouro da matriz
exit
endif
if ylib_len(alltrim(opcoes[ct2][2])) == 0
if upper(transform(opcoes[ct2][3],"L")) <> "T" .and. upper(transform(opcoes[ct2][3],"L")) <> "F"
if ylib_len(alltrim(opcoes[ct2][3])) <> 0
aadd(mVertical,{opcoes[ct2][3],opcoes[ct2][4],opcoes[ct2][5],opcoes[ct2][6]})
else
if !(tagSubmenu $ mVertical[len(mVertical)][1])
mVertical[len(mVertical)][1] += tagSubmenu // verificando submenus vinculados
endif
endif
endif
endif
endif
next
// Verificando a posição do Menu Vertical
xc1 = c1
for ct:= 2 to escolhaopcao[1]
xc1 += ylib_len(mHorizontal[ct][1]) + espacamento
next
// Verificando o tamanho do primeiro menu vertical
tam:= 0
tamvertical :=0
contador:=0
for ct:= 1 to len(mVerticalOLD)
tam:= max(tam,ylib_len(mVerticalOLD[ct][1]))
if ylib_len(alltrim(mVerticalOLD[ct][1])) <> 0 .and. alltrim(mVerticalOLD[ct][2]) <> "-"
++ contador
endif
if contador <= escolhaopcao[2] .and. mVerticalOLD[ct][1] == "-"
++tamvertical
endif
next
deslocamento = mVertical[1][4]
// xc1 += int(tam/2.5) + deslocamento[2] // posicao do menu vertical 2
xc1 += int(tamMenu[1]/4) + deslocamento[2]
tamMenu[2] :=0 // tamanho menu
for ct:=1 to len(mVertical)
tamMenu[2]:=max(tamMenu[2],ylib_len(mVertical[ct][1]))
next
tamMenu[2]:=tamMenu[2]+4
save screen to tela2
opc := ylib_criaMenuVertical(l1+1+escolhaopcao[2]+tamVertical+1+deslocamento[1],xc1,mVertical,corMenu,lstatus,corMenuDesabilitado,tiposombra,corSombra)
escolhaopcao[3] = opc // guarda o menu escolhido
ret += "."+alltrim(str(opc)) // gerencia o retorno da função
// Verificando a opção escolhida (excluindo separadores de menu)
contador := 0
for ct:= 1 to len(mVertical)
if (alltrim(mVertical[ct][1]) <> "-")
++contador
endif
if opc == contador
verifica := mVertical[ct][1]
exit
endif
next
if opc == 0 // tecla ESC
restore screen from tela2
// Rotina para voltar ao menu anterior usando ESC
mVertical = {}
nivel := 1
for ct:= 1 to 2
tmp := rat(".",ret)
ret := substr(ret,1,tmp-1)
next
restore screen from tela1
loop
else
if !(tagSubmenu $ verifica) // se não tem um submenu cai fora
exit
endif
endif
nivel := 3
endif // fim do nivel 2 do menu
// gerenciando o menu vertical de nÃvel 3 =====================================================================
// Pegando os menus verticais
if nivel <= 3 // nivel 3 do menu
if marca =.f.
mverticalOLD:= mVertical
endif
mVertical := {}
contador := 0
for ct2:= 1 to len(opcoes) // primeira opcao
if ylib_len(alltrim(opcoes[ct2][1])) <> 0
++ contador
endif
// verificando a opção escolhida
if contador == escolhaopcao[1]
ct:= ct2
exit
endif
next
contador:=0 // segunda opcao
for ct2:= (ct+1) to len(opcoes)
if ylib_len(alltrim(opcoes[ct2][2])) <> 0 .and. alltrim(opcoes[ct2][2]) <> "-"
++ contador
endif
// verificando a opção escolhida
if contador == escolhaopcao[2]
ct:= ct2
exit
endif
next
contador:=0
for ct2:= (ct+1) to len(opcoes) // terceira opcao
if upper(transform(opcoes[ct2][3],"L")) <> "T" .and. upper(transform(opcoes[ct2][3],"L")) <> "F"
if ylib_len(alltrim(opcoes[ct2][3])) <> 0 .and. alltrim(opcoes[ct2][3]) <> "-"
++ contador
endif
endif
// verificando a opção escolhida
if contador == escolhaopcao[3]
if ct2 > len(opcoes) // Verifica o estouro da matriz
exit
endif
if ylib_len(alltrim(opcoes[ct2][3])) == 0
if !isarray(opcoes[ct2][4])
if upper(transform(opcoes[ct2][4],"L")) <> "T" .and. upper(transform(opcoes[ct2][4],"L")) <> "F"
if ylib_len(alltrim(opcoes[ct2][4])) <> 0
aadd(mVertical,{opcoes[ct2][4],opcoes[ct2][5],opcoes[ct2][6],opcoes[ct2][7]})
else
if !(tagSubmenu $ mVertical[len(mVertical)][1])
mVertical[len(mVertical)][1] += tagSubmenu // verificando submenus vinculados
endif
endif
endif
endif
endif
endif
next
// Verificando a posição do Menu Vertical
xc1 = c1
for ct:= 2 to escolhaopcao[1]
xc1 += ylib_len(mHorizontal[ct][1]) + espacamento
next
// Verificando o tamanho do primeiro menu vertical
tam:= 0
tamvertical :=0
contador:=0
for ct:= 1 to len(mVerticalOLD)
tam:= max(tam,ylib_len(mVerticalOLD[ct][1]))
if ylib_len(alltrim(mVerticalOLD[ct][1])) <> 0 .and. alltrim(mVerticalOLD[ct][2]) <> "-"
++ contador
endif
if contador <= escolhaopcao[2] .and. mVerticalOLD[ct][1] == "-"
++tamvertical
endif
next
deslocamento = mVertical[1][4]
// xc1 += (int(tam/2.5) * 2) +deslocamento[2] //+nTam // posicao do menu vertical 2
xc1 += int((tamMenu[1]/4)+(tamMenu[2]/4)) + deslocamento[2]
tamMenu[3] :=0 // tamanho menu
for ct:=1 to len(mVertical)
tamMenu[3]:=max(tamMenu[3],ylib_len(mVertical[ct][1]))
next
tamMenu[3]:=tamMenu[3]+4
save screen to tela3
opc := ylib_criaMenuVertical(l1+1+escolhaopcao[2]+escolhaopcao[3]+tamVertical+2+deslocamento[1],xc1,mVertical,corMenu,lstatus,corMenuDesabilitado,tiposombra,corSombra)
escolhaopcao[4] = opc // guarda o menu escolhido
ret += "."+alltrim(str(opc)) // gerencia o retorno da função
// Verificando a opção escolhida (excluindo separadores de menu)
contador := 0
for ct:= 1 to len(mVertical)
if (alltrim(mVertical[ct][1]) <> "-")
++contador
endif
if opc == contador
verifica := mVertical[ct][1]
exit
endif
next
if opc == 0 // tecla ESC
restore screen from tela3
mVertical = {}
nivel := 2
for ct:= 1 to 2
tmp := rat(".",ret)
ret := substr(ret,1,tmp-1)
next
restore screen from tela2
loop
else
if !(tagSubmenu $ verifica) // se não tem um submenu cai fora
exit
endif
endif
menu := 4
endif // fim do nivel 3 do menu
// gerenciando o menu vertical de nÃvel 4 =====================================================================
// Pegando os menus verticais
if nivel <= 4 // nivel 4 do menu
if marca =.f.
mverticalOLD:= mVertical
endif
mVertical := {}
contador := 0
for ct2:= 1 to len(opcoes) // primeira opcao
if ylib_len(alltrim(opcoes[ct2][1])) <> 0
++ contador
endif
// verificando a opção escolhida
if contador == escolhaopcao[1]
ct:= ct2
exit
endif
next
contador:=0 // segunda opcao
for ct2:= (ct+1) to len(opcoes)
if ylib_len(alltrim(opcoes[ct2][2])) <> 0 .and. alltrim(opcoes[ct2][2]) <> "-"
++ contador
endif
// verificando a opção escolhida
if contador == escolhaopcao[2]
ct:= ct2
exit
endif
next
contador:=0 // terceira opcao
for ct2:= (ct+1) to len(opcoes)
if upper(transform(opcoes[ct2][3],"L")) <> "T" .and. upper(transform(opcoes[ct2][3],"L")) <> "F"
if ylib_len(alltrim(opcoes[ct2][3])) <> 0 .and. alltrim(opcoes[ct2][3]) <> "-"
++ contador
endif
endif
// verificando a opção escolhida
if contador == escolhaopcao[3]
ct:= ct2
exit
endif
next
contador:=0
for ct2:= (ct+1) to len(opcoes) // quarta opcao
if !isarray(opcoes[ct2][4])
if upper(transform(opcoes[ct2][4],"L")) <> "T" .and. upper(transform(opcoes[ct2][4],"L")) <> "F"
if ylib_len(alltrim(opcoes[ct2][4])) <> 0 .and. alltrim(opcoes[ct2][4]) <> "-"
++ contador
endif
endif
endif
// verificando a opção escolhida
if contador == escolhaopcao[4]
if ct2 > len(opcoes) // Verifica o estouro da matriz
exit
endif
if ylib_len(alltrim(opcoes[ct2][4])) == 0
if !isarray(opcoes[ct2][4])
if upper(transform(opcoes[ct2][5],"L")) <> "T" .and. upper(transform(opcoes[ct2][5],"L")) <> "F"
if ylib_len(alltrim(opcoes[ct2][5])) <> 0
aadd(mVertical,{opcoes[ct2][5],opcoes[ct2][6],opcoes[ct2][7],opcoes[ct2][8]})
else
if !(tagSubmenu $ mVertical[len(mVertical)][1])
mVertical[len(mVertical)][1] += tagSubmenu // verificando submenus vinculados
endif
endif
endif
endif
endif
endif
next
// Verificando a posição do Menu Vertical
xc1 = c1
for ct:= 2 to escolhaopcao[1]
xc1 += ylib_len(mHorizontal[ct][1]) + espacamento
next
// Verificando o tamanho do primeiro menu vertical
tam:= 0
tamvertical :=0
contador:=0
for ct:= 1 to len(mVerticalOLD)
tam:= max(tam,ylib_len(mVerticalOLD[ct][1]))
if ylib_len(alltrim(mVerticalOLD[ct][1])) <> 0 .and. alltrim(mVerticalOLD[ct][2]) <> "-"
++ contador
endif
if contador <= escolhaopcao[2] .and. mVerticalOLD[ct][1] == "-"
++tamvertical
endif
next
deslocamento = mVertical[1][4]
// xc1 += (int(tam/2.5) * 4) + deslocamento[2] // +int(nTam/2) // posicao do menu vertical 3
xc1 += int((tamMenu[1]/4)+(tamMenu[2]/4)+(tamMenu[3]/4)) + deslocamento[2]
tamMenu[4] :=0 // tamanho menu
for ct:=1 to len(mVertical)
tamMenu[4]:=max(tamMenu[4],ylib_len(mVertical[ct][1]))
next
tamMenu[4]:=tamMenu[4]+4
save screen to tela4
opc := ylib_criaMenuVertical(l1+1+escolhaopcao[2]+escolhaopcao[3]+escolhaopcao[4]+tamVertical+3+deslocamento[1],xc1,mVertical,corMenu,lstatus,corMenuDesabilitado,tiposombra,corSombra)
escolhaopcao[5] = opc // guarda o menu escolhido
ret += "."+alltrim(str(opc)) // gerencia o retorno da função
// Verificando a opção escolhida (excluindo separadores de menu)
contador := 0
for ct:= 1 to len(mVertical)
if (alltrim(mVertical[ct][1]) <> "-")
++contador
endif
if opc == contador
verifica := mVertical[ct][1]
exit
endif
next
if opc == 0 // tecla ESC
restore screen from tela4
mVertical = {}
nivel := 3
for ct:= 1 to 2
tmp := rat(".",ret)
ret := substr(ret,1,tmp-1)
next
restore screen from tela3
loop
else
if !(tagSubmenu $ verifica) // se não tem um submenu cai fora
exit
endif
endif
endif // fim do nivel 4 do menu
exit // retirar para mais nÃveis...
enddo
return ret
//==================================================================================
function isarray(vet) // verifica se a entrada e um vetor
local ret := .t., ct
BEGIN SEQUENCE WITH {| oErr | Break( oErr ) }
ct := vet[1]
RECOVER
ret:= .F.
END SEQUENCE
return ret
//===================================================================================
func ylib_avancarMenuHorizontal()
keyboard chr(27)
navega:=1
return NIL
// ==================================================================================
func ylib_voltarMenuHorizontal()
keyboard chr(27)
navega:=2
return NIL
//===================================================================================
[]s
Yugi