Lisp, Dcl e duplo clique

Vou desenferrujar um pouco o meu lisp, hehehe
respondendo ao desafio do crackster, sim é possível implementar duplo clique no dcl quando o fazemos sobre list_box

segundo o help (F1!!!!), ao clicarmos, selecionarmos algum controle da nossa dcl, ela informa atravez do seu "action" qual foi a $key, o $value e tambem o $reason do controle que foi acessado. Veja quais são as $reason possíveis:
1 = pressionou enter em um controle qualquer, um edit_box por exemplo
2 = somente em edit_box. O cara tirou do foco do controle, clicando o TAB por exemplo
3 = sliders, o cara tirou o foco do controle, clicando o TAB por exmeplo
4 = list_box e image_button, o cara deu duplo clique ou clique simples

na verdade é um pouco mais complexo que isso, mas em linhas gerais é por aí

para testarmos então esse duplo clique, analize este programa, primeiro o dcl:

teste : dialog {
  label = "Teste duplo clicque" ;
  :
boxed_column {
     label="Dê duplo clique num item";
    :
list_box { key = "lista"; } }
  :button {
     key = "cancel";
     is_cancel=true;
     label="Cancela";}}


agora o lisp:

(defun c:teste (/ dcl lista acao n)
;carrega o dcl na memória  
  (setq dcl (load_dialog "d:/teste.dcl")
;lista de item do listbox:
    lista '("pedra" "papel" "tesoura")
;variavel auxiliar para armazenar o item escolhido:
    n    nil
;função anonima para proceder as ações do dcl:
    acao (lambda (key value reason)
;testa qual controle foi chamado:
           (cond ((= key "lista")
;se foi o list_box, e se foi duplo clique (reason==4)
              (if (= reason 4)
            (
progn
;mostre qual foi o item selecionado
              (alert (setq n (nth (atoi value) lista)))
;encerre o dcl com um "OK"
              (done_dialog 1))))
;aqui iria a ação de outros controles...
             )))

;inicia o quadro de dialogo
  (new_dialog "teste" dcl)

;preenche a lista de itens do list_box:
  (start_list "lista" 3)
  (
foreach o lista (add_list o))
  (
end_list)

;|define qual é a ação do nosso list_box
  se tivessemos mais uns 20 controles, todos eles teriam
 a mesma ação e poderiamos fazer:
 (foreach k '("lista" "key1" "key2" "keyn")
   (action_tile k "(acao $key $value $reason)") )
 |;

  (action_tile "lista" "(acao $key $value $reason)")

;interpreta a saida do dialogo apos iniciar ele:
  (if (= 1 (start_dialog))
;| se done_dialog é 1, clicou OK ou no nosso caso, como não temos um botão OK
 foi o duplo clique quem encerrou o DCL
 se clicarmos o botão cancela, o done_dialog devolve 0
 claro que se queremos interromper o dcl por outro motivo, é só colocar
 (done_dialog NUM)
 onde NUM seria um inteiro qualquer que testariamos neste IF
 |;

    (alert (strcat  "Voce escolheu um item!!!\n Ele é: " n)))
;descarrega o dcl:
  (unload_dialog dcl)
  )



Note que fiz algumas considerações no código.
basicamente, mostrei como poderíamos sobreescrever o botão CANCEL.

Se quizesse mudar o OK, tambem daria, bastaria colocar uma propriedade (is_default = true;) num controle de botão (button)

veja como preenchi a lista do list_box. Muita gente coloca os itens na propriedade list ( list = "1\n2\n3" ; ) dentro do arquivo do dcl, mas ai fica ruim para obter o texto do item selecionado

também optei por definir o action_tile dos controles via lisp e não no dcl.
iso facilita a escrita do programa, pois você não precisa escrever o código dentro de string.

por fim, dei a dica de como encerrar o dcl por outro motivo.
Qual motivo?

Por exmeplo, digamos que algum controle do dcl seja um botão para capturar uma coordenada na tela com a função getpoint do lisp.

Não poderíamos simplesmmente colocar uma ação assim:

(action_tile "botao" "(setq pt (getpoint \"Clique um ponto\"))")

ao clicar o botão, isso causaria um erro fatal no seu cad!!!! já discuti isso aqui no blog algumas vezes...


neste caso a solução seria fazer um looping, jogando a parte que pede o ponto para DEPOIS de encerrar o dcl:

(setq faz t)
(
while faz
  (new_dialog "teste" dcl)

  ;|subrotinas que preenchem os controles|;
  (action_tile "botao" "(done_dialog 2)")
  
  
  (
setq dlg (start_dialog))
  (
cond ((= dlg 0) (alert "clicou CANCEL") (setq faz nil))
    ((
= dlg 1) (alert "clicou OK"))
    ((
= dlg 2) (setq pt (getpoint "\nEntre com o ponto")))))




Percebe? assim o looping é executado até que clicamos o botão CANCELA

é isso....
gostou? deixe um comentário!!!

LinkWithin

Related Posts Plugin for WordPress, Blogger...