﻿                   Tutorial Tcl/Tk
                   =====================================
                                                                                                                             
                   Danilo Pacheco Martins <Danilo@infocont.com.br>
                   Fernando Wuthstrack <fernando@infocont.com.br>
                                                                                                                             
                   Quinta, 27 de maio de 2006
                                                                                                                             
                                                                                                                             
Resumo
------
                                                                                                                             
     Este tutorial tem por objetivo ser uma referencia ao aprendizado no uso do
     Tcl/Tk. E uma otima ferramenta para desenvolvimento grafico, e a sua grande
     vantagem de rodar em varias plataformas, sem que seja preciso mudar seu fonte.
     Duvidas, criticas e sugestoes favor postar para o e-mail: danilo@infocont.com.br
--------------------------------------------------------------------------------------

Conteudo
--------
1 - O que e Tcl/Tk.
2 - Conceitos basicos do Tcl/Tk.
3 - Fazendo o Cobol "conversar" com o Tcl/TK.
4 - Instalando o Tcl/TK no Windows.
5 - Compilando o programa cadastro.cob.
6 - Duvidas.
7 - Apendice.

--------------------------------------------------------------------------------------
1 - O que e Tcl/Tk

    Tcl (Tool Command Language) e uma linguagem de script usada por meio milhao de 
    programadores ao redor do mundo e se tornou um componente critico em milhares de 
    corporacoes. Ele tem uma sintaxe simples e programavel e pode ser usado como uma 
    aplicacao standalone ou embutida em outras aplicacoes. O melhor de tudo, e que o Tcl 
    e Open Source e completamente gratis.

    Tk e um toolkit para criacao de interface graficas com o usuario, possibilitando assim
    criar GUIs poderosas e inacreditavel mente rapidas, ao contrario de aplicacoes 
    desenvolvidas em outras linguagens Interpretadas ou ate mesmo pre compiladas. 
    Provou-se tao popular que agora vem em todas as distribuicoes do Tcl.
    
    Tanto o Tcl como o Tk foram desenvolvidos por John Ousterhout. Programadores seguiram
    o exemplo dele no mundo inteiro e construiram as proprias extensoes de Tcl. Hoje, ha
    centenas de extensoes do Tcl para todas as necessidades de aplicacoes.
    
    Tcl e Tk sao altamente portateis e sao executadas praticamente todos os sabores de 
    Unix, (Linux, Solaris, IRIX, AIX, *BSD *), nao podemos deixar de falar que ha suporte
    para o Windows e Macintosh. Ha varios locais que proveem binarios de precompiladores 
    para varias plataformas.

    Tcl e Tk sao Open Source e o desenvolvimento continuo dele e feito com a colaboracao
    dos engenheiros da Scriptics (www.scriptics.com) e usuario da comunidade Tcl. A 
    Scriptics mantem um repositorio de CVS para o codigo fonte.

    Todos podem enviar mudancas e correcoes ao codigo fonte do Tcl/TK. Caso seja 
    encontrado algum erro no Tcl/TK voce podera comunica-lo diretamente a Scriptics 
    utilizando o relatorio de Bugs.

    1.1 - Tcl: A Plataforma de Integracao
   
    Hoje em dia um dos grandes problemas enfrentado pelos desenvolvedores de solucoes e 
    a diversidade de plataformas que poderao ser encontradas nas empresas. O Tcl e chamado 
    de programacao de aplicacoes para integracao.
    Para empreendimentos, a plataforma de integracao esta ficando tao estrategicamente 
    importante quanto o Sistema Operacional e os bancos de dados.
    Tcl e a melhor plataforma de integracao por causa de sua velocidade de uso, largura de 
    funcionalidade, e caracteristicas para empreendimento prontas como linha-seguranca, 
    internacionalizacao e desenvolvimento multiplataforma.

    O comentario acima foi feito com base no Site: http://tclbrasil.cipsga.org.br/tcltk.htm
--------------------------------------------------------------------------------------

2  -  Conceitos basicos do Tcl/Tk.

2.1 - Janela principal.

2.1.1 Definindo titulo da janela.
      wm title . "Titulo da Janela"

2.1.2 Definindo tamanho da janela.
      wm geometry . XXXxYYY
      Ex: wm geometry . 500x500

2.2 - Variaveis

2.2.1 Declarando as variaveis do Cobol.
      As variaveis vindas do Cobol tem por obrigatoriedade ser do tipo string e terao
      que ter o mesmo tamanho declarado no fonte Cobol. A forma de passagem de parametros
      do Cobol para o Tcl/Tk sera tratada mais adiante. A declaracao do grupo
      "cobol_fields" e obrigatoria e nao pode ser alterada.

      set cobol_fields {
      variavel_1      5
      variavel_2      25
      variavel_3      40
      }
      Observacao: O numero apos o nome da variavel e' o seu tamanho.

2.2.2 Definindo um valor para uma variavel.
      Para definir um valor para uma variavel, voce usara a seguinte sintaxe:
      set nome_da_variavel valor
      Ex:
      set vnome Jose
      Neste caso ele inseriu o nome "Jose" na variavel "vnome", o valor atribuido nao
      precisa necessariamente estar entre "" (aspas), a nao ser que voce queira
      inserir mas de uma palavra, como por ex:
      vnome set "Jose da Silva"

2.2.3 Recebendo o valor de uma variavel.
      Sempre que voce quiser receber o valor de uma variavel, ela tera que ser 
      precedida do "$" (dolar), como por exemplo:
      set vnome1 $vnome2
      Neste caso a variavel "vnome1" recebeu o valor da variavel "vnome2"

2.3 - Inserindo uma condicao.
      O comando if e utilizado para avaliar se uma condicao. dada e verdadeira ou 
      falsa. Caso a condicao seja verdadeira ele podera executar uma serie de comandos
      ou, se falsa, ira executar outra serie de comandos de acordo com o definido 
      pelo programador.
      Sintaxe:
      if {condicao1} [then] {corpo se verdadeiro} [else {corpo se falso} [elseif {condicao2} {corpo}]]
      onde:
      {condicao1}, e a primeira condicao a ser avaliada
      [then], e opcional apos a condicao que sera avaliada, e utilizado para indicar
      o que sera executado caso a condicao seja verdadeira.
      {corpo se verdadeiro}, e o que sera executado se a condicao avaliada for 
      verdadeira.
      [else], e utilizado para indicar algo que devera ser feito se a condicao 
      avaliada for falsa.
      {corpo se falso}, e o que devera ser executado quando a condicao avaliada for
      falsa.
      [elseif], e utilizado para fazer uma segunda verificacao condicional dentro do 
      mesmo if.
      {condicao2}, e a segunda condicao que sera avaliada pelo elseif.
      {corpo}, o mesmo que {corpo se verdadeiro}.

2.4 - Inserindo uma rotina de repeticao.
      O comando while ira executar uma serie de comandos enquanto uma condicao for 
      verdadeira, caso na primeira verificacao ja for verificado que a condicao e 
      falsa nenhum comando do corpo sera executado, semelhante ao PERFORM do Cobol.
      Sintaxe:
      while {condicao} {corpo}
      Onde:
      {condicao}, sera a condicao verificada a cada loop para continuar ou parar o
      laco de repeticao.
      {corpo}, sao os comandos que deverao ser repetidos a cada loop
      Exemplo:
      set var1 0
      while {$var1 < 10} {
          incr var1
      }

2.5 - Procedures.
      E possivel no Tcl criar procedures (semelhante o PERFORM do Cobol), a sintaxe:
      proc {valores} {corpo}
      Exemplo: 
      proc atribui_valor {a b c} {
         set valor1 $a
         set valor2 $b
         set valor3 $c
       }
      A chamada da procedure acima, seria feita da seguinte maneira:
      atribui_valor "primeiro" "segundo" "terceiro"

2.6 - Bind.
      O comando bind e utilizado para associar eventos do teclado ou mouse a objetos
      do Tk. Exemplo:
      label .lab 
      entry .entcodigo
      bind .entcodigo <FocusIn> {.lab configure -text "Voce entrou no campo Codigo"}
      bind .entcodigo <FocusOut> {.lab configure -text "Voce saiu do campo Codigo"}
      No caso acima, quando o cursor entrar no ".entcodigo", o ".lab" vai exibir: 
      "Voce entrou no campo Codigo", e quando sair ele vai exibir: "Voce saiu do campo
      Codigo"
       
2.7 - Componentes Tk.
      Existem varios componente do Tk, em nosso tutorial usamos entry, label, button
      e listbox. Todo nome atribuido a um componente deve proceder de um ponto ".".

2.7.1 Label.
      Label e um componente de texto, apenas para exibir(ex: identificar campos).
      Grotescamente podera ser comparado ao DISPLAY do Cobol.
      A sintaxe para criar um label e a seguinte:
      label nome_do_label
      Exemplo:
      label .codigo
      No caso acima ele criou um label com o nome "codigo".
      Existem varias propriedades para um label, como por exemplo -text, -foregorund,
      -background e etc.
      Exemplo:
      label .codigo -text Codigo -foreground blue -background white
      No caso acima, o label codigo tera o valor "Codigo", letra azul e fundo branco.
      Observacao: se voce quiser que o texto do label tenha mais de uma palavra, voce 
      tera que coloca-lo entre "" (aspas). Exemplo: -text "InfoCont Sistemas Integrados"
      Para associar a propriedade -text a uma variavel, voce tera que declara-la da
      seguinte maneira:
      -textvariable var
      Neste caso, sempre que a variavel "var" mudar de valor, o texto do label tambem 
      sera modificado.
      
2.7.2 Entry.
      Entry e um componente ao qual permite com que voce atribua valor a sua 
      propriedade texto via teclado. Semelhante ao ACCEPT do Cobol.
      A sintaxe para criar um entry e a seguinte:
      entry nome_do_entry
      Exemplo:
      entry .endereco
      No caso acima ele criou um entry com o nome de "endereco".
      Existem varias propriedade para um entry, como por exemplo -text, -foreground,
      -background e etc.
      Exemplo:
      entry .endereco -text desendereco -foreground blue -background white
      Neste caso, o entry "endereco" ira atualizar o valor da variavel "desendereco",
      com letra azul e fundo branco.

2.7.3 Button.
      Button e um componente que aciona algum procedimento quando acionado.
      A sintaxe para criar um Button e a seguinte:
      button .nome_do_botao
      Exemplo:
      button .but
      No caso acima ele criou um botao com o nome de "but"
      Existem varias propriedade para um botao, como por exemplo -text, -foregorund,
      -background -command e etc.
      Exemplo:
      button .but -text Sair -foreground blue -command {exit}
      Neste caso, o rotulo do botao "but" sera "Sair", letra azul e fechara a tela 
      quando ele for acionado, se voce quiser fazer mais de um procedimento quando
      um botao for acionado, voce tera que separar um procedimento do outro com ";" 
      (ponto-e-virgula).

2.7.4 ListBox.
      ListBox e um componente que mostra uma lista de itens.
      A sintaxe para criar um ListBox e a seguinte:
      listbox .lista
      No caso acima ele criou um listbox com o nome de "lista"
      Existem varias propriedades para um listbox, como por exemplo  -selectmode
      -yscrollcommand e etc.
      -Exemlo:
      listbox .lista -selectmode browse -yscrollcommand {.rolagemv set}
      Neste caso ele definiu o tipo de selecao como "browse" a associou uma barra
      de rolagem vertical, que sera utilizada quando o numero de itens for superior 
      ao tamanho fisico do componente (vide scrollbar).

2.7.5 Scrollbar.
      Scrollbar e um componente que serve como barra de rolagem para outros 
      componentes.
      A sintaxe para criar um Scrollbar e a seguinte:
      scrollbar nome_do_scrollbar
      Existem varias propriedades para um Scrollbar, como por exemplo -orient
      e -command 
      Exemplo:
      listbox .lista -selectmode browse -yscrollcommand {.rolagemv set}
      scrollbar .rolagemv  -orient vertical -command {.lista yview}
      Neste caso ele criou um listbox e um scrollbar, onde o scrollbar esta na 
      vertical, e ele ira mover para cima ou para baixo a lista do ListBox.

2.7.6 TopLevel
      TopLevel, e um comando que cria uma nova janela.
      A sintaxe para criar um toplevel e a seguinte:
      toplevel  .nome_janela
      Exemplo:
      toplevel .cadastro
      No caso acima ele criou uma nova janela com o nome de "cadastro"
      Para setar a altura usa-se o comando -height altura_da_janela
      para setar a largura usa-se o comando -width largura_da_janela
      se voce quiser criar algum componente nesta janela voce tera que colocar o nome
      da janela antes do nome do componente, como por exemplo:
      button .cadastro.but -text "Sair" -command {exit}
      No caso acima ele criou um botao chamado "but" na janela chamada "cadastro" o 
      rotulo desse botao e "Sair" e quando ele for pressionado, ele ira fechar o 
      programa.

2.8 - Place.
      O Place e um comando com a utilidade de posicionar os objetos na janela.
      Sua sintaxe e a seguinte:
      place nome_do_objeto -x posicao_horizontal -y posicao_vertical
      -height altura -width largura
      Comandos principais:
      -x : indica quantos pixels na horizontal o objeto deve se posicionar.
      -y : indica quantos pixels na vertical o objeto deve se posicionar.
      -height : indica a altura do objeto em pixels.
      -width : indica a largura do objeto em pixels.
      Exemplo:
      place .entcidade -x 10 -y 15 -height 20 -width 170
      No caso acima o componente "entcidade" estara 10 pixels na horizontal, da
      janela criada 15 pixels na vertical, 20 pixels de altura, e 170 pixels de 
      largura.

2.9 - Grid.
      Grid e um outro metodo para organizar objetos na tela, muito mais
      pratico que o place, ele cria uma tabela invisivel na tela, e voce vai
      colocando cada widget em uma celula dessa tabela, facilitando o trabalho, pois
      voce nao precisa ficar se preocupando em alinhar os objetos, o grid faz isso
      sozinho, o largura da coluna, e' do tamanho do componente mais largo da coluna,
      e a altura da linha, e' o tamanho do componente mais alto da linha. Exemplo:
       button .but1
       button .but2
       button .but3
       button .but4
       grid .but1 .but2
       grid .but3 .but4
      no caso acima foi criado quatro botoes e exibido na tela com o comando grid,
      existem varias opcoes para o grid, como por exemplo:
      -sticky nsew, isso indicara em que posicao da celula ficara o objeto, caso a
      celula seja maior que o objeto, nesse exemplo, ela ficara na posicao norte, sul, leste
      e oeste, ou seja, o tamanho do objeto, sera o tamanho da celula.

2.10  Pack.
      Pack, e' uma outra maneira de se organizar objetos na tela. E' como se
      ele jogasse os objetos para os cantos, na opcao -side voce define em que canto
      o objeto sera jogado: para cima(top), para a esquerda(left), direita(right) ou 
      para baixo(bottom). A opcao -anchor, em que posicao do lado o objeto
      ira ficar, norte(n), sul(s), leste(e) ou oeste(w) por exemplo:
       button .but1
       button .but2
       button .but3
       button .but4
       pack .but1 .but2 .but3 .but4 -side right -anchor nw
      Nesse exemplo, foram criados quatro botoes, eles irao aparecer no canto direito 
      superior, nao importando se voce altere o tamanho da janela.

--------------------------------------------------------------------------------------

3 - Fazendo o Cobol "conversar" com o Tcl/TK.

3.1 - Trabalhando com as variaveis do Cobol.
      As variaveis associadas ao Tcl/TK, deverao ser declaradas na 
      WORKING-STORAGE SECTION. Voce ira declarar uma variavel do nivel 1, e as 
      variaveis pertencentes ao Tcl/TK deverao estar dentro dela, o nome das variaveis, 
      fica a seu criterio. Sera necessario declarar mais uma variavel PIC X(64) que 
      servir para identificar o nome do arquivo TCL. Veja o exemplo abaixo:
      01 VARIAVEIS-TCL.
         03 TCL-CODIGO                  PIC X(04).
         03 TCL-NOME                    PIC X(40).
         03 TCL-ENDERECO                PIC X(40).
      01 NOME-TELA                      PIC X(64).
      Neste exemplo, declaramos a variavel "VARIAVEIS-TCL", nela estarao todas as 
      variaveis que o Tcl/TK ira usar. E imprescindivel que o tamanho das variaveis no  
      Cobol seja o mesmo das variaveis declaradas no Tcl/Tk e que tem por obrigatoriedade 
      ser PIC X, tendo em vista que o Tcl/Tk nao permite a declaracao de campos numericos.
      Posteriormente declaramos a variavel "NOME-TELA", que sera o nome do arquivo da tela 
      (script Tcl/Tk) que voce ira chamar. Digamos que fizemos uma tela com o nome de 
      "cadastro.tcl", entao a variavel "NOME-TELA" receberia o valor "cadastro.tcl".
      Veja no indice 3.2 (proximo) para saber como elas serao usadas.
      
3.2 - Chamando a tela.
      Antes de tudo voce tera que chamar o programa "initTcl". Ele inicializa o 
      ambiente grafico. Faca isso no comeco do programa, antes de comecar qualquer 
      rotina.
      A chamada da tela Tcl/TK e efetuada atraves da rotina "tcleval", que e 
      um programa escrito em linguagem C, que possui um interpretador de scripts TCL/TK.
      Ele e responsavel por executar a tela e transportar os conteudos das variaveis 
      do Cobol para o Tcl/TK e vice-versa.
      Para chamar a tela, voce tera que executar o programa "tcleval" atraves do 
      comando CALL, usando as variaveis do Tcl/Tk e a variavel com o nome do programa, 
      usando o mesmo exemplo anterior:
      01 VARIAVEIS-TCL.
         03 TCL-CODIGO                  PIC X(04).
         03 TCL-NOME                    PIC X(40).
         03 TCL-ENDERECO                PIC X(40).
      01 NOME-TELA                      PIC X(64).
      Digamos que a tela que voce ira chamar, e "cadastro.tcl", entao no Cobol fariamos 
      da seguinte maneira.
      MOVE "cadastro.tcl" TO NOME-TELA.
      CALL "tcleval" USING VARIAVEIS-TCL NOME-TELA.
      No caso acima, quando o CALL fosse executado, ele chamaria a tela escrita em Tcl/TK
      "cadastro.tcl" e as variaveis do "cobol_field" no Tcl/TK receberiam os valores 
      vindos do Cobol.

3.3 - Voltando para o Cobol.
      Voltar do Tcl/TK para o Cobol, e muito simples, voce tera que executar
      no Tcl/TK o comando "do_exit", fazendo isso os valores das variaveis do "cobol_fields" 
      serao movida para as variaveis do Cobol, conforme voce declarou na 
      WORKING-STORAGE SECTION, dai cabe a voce fazer uma rotina, para que o Cobol receba os 
      valores e volte para a chamar a tela, mostrando os novos valores processados. 

3.4 - Como funciona a rotina do tutorial.
      No exemplo do nosso tutorial, temos uma variavel declarada no Cobol com o nome de 
      "TCL-OPCAO", com a correspondente "tclopcao" no Tcl/TK. 
      O Cobol chama o Tcl/TK atraves do "tcleval" e a tela e exibida. Quando voce clica 
      em algum botao, ou tira o foco do campo "codigo", ele atribui a acao para a variavel 
      tclopcao e executa o "do_exit". Este comando ira retornar o processamento para
      o Cobol, transportando as variaveis vindas do Tcl/TK. O Cobol le a variavel 
      "TCL-OPCAO" e executa a rotina correspondente a opcao e retorna para o Tcl/Tk.
      Exemplo:
      Na WORKING-STORAGE SECTION atribuimos a variavel "NOME-PROGRAMA" com o valor 
      "cadastro.tcl", que e o nome do arquivo do Tcl/TK.
      No inicio do programa Cobol executamos o "iniTcl" (CALL "initTcl".).
      Antes de chamar a tela pela primeira vez inicializamos as variaveis que serao 
      usadas pelo Tcl/TK, para que tela seja exibida com os campos vazios.
      Como a variavel "NOME-PROGRAMA" ja esta carregado com o nome da janela, 
      chamamos a tela (CALL "tcleval" USING VARIAVEIS-TCL NOME-PROGRAMA).
      Isto ira chamar a tela do Tcl/TK. Digamos que o usuario queira gravar um registro, 
      entao ele ira preencher os dados e depois ira clicar no botao "Gravar". Quando ele 
      clicar em gravar, o Tcl/TK ira atribuir a variavel "tclopcao" o valor "gra" e fara 
      o comando "do_exit" (-command {set tclopcao gra ; do_exit}) que ira fazer com que o
      processamento retorne ao programa Cobol, com os novos valores da variaveis.
      O Cobol ira ler a variavel "TCL-OPCAO", que tera o valor "gra", e executara um 
      PERFORM para a secao "1000-GRAVA", onde os valores das variaveis vindas do Tcl/TK
      serao movidas para a FD "CADASTRO" e sera executa a gravacao. Na seqüencia o
      programa inicializara as variaveis do Tcl/TK, atribuira uma mensagem descrevendo
      o resultado do processo de gravacao para a variavel "TCL-MENSAGEM" e saira da rotina, 
      retornando ao Tcl/TK (tcleval). A tela sera exibida com o novos valores vindos do
      Cobol. No script Tcl/TK temos um label que esta vinculada a variavel "tclmensagem",
      que no retorno sera atualizada e exibira ao usuario o resultado da acao.
      Resumido, o Cobol chama o Tcl/TK, o usuario modificara os valores das variaveis, 
      voltara para o Cobol. O Cobol, por sua vez, ira identificar o desejo do usuario,
      ira executar o processo correspondente e retornara ao Tcl/TK, 
--------------------------------------------------------------------------------------


4 - Instalando o Tcl/TK no Windows.

4.1 - O melhor caminho para baixar o TCL/TK para Windows é através pacote ActiveTCL, 
      distribuido pela ActiveState. O interpretador TCL/TK é totalmente free.
      Para realizar o download do ActiveTCL, acesse o endereço abaixo:
      
      http://www.activestate.com/Products/ActiveTcl

      O ActiveTCL trás, além do interpretador TCL/TK, inúmeros pacotes de componentes, 
      como o Iwidget e o Bwidgets, que agregam funções como suporte à campos editados, 
      calendários, utilitários para busca e seleção de arquivos e inúmeros outros recursos.
      A instalação do ActiveTCL também é bastante simples, sendo necessário apenas confirmar 
      todos os passos do processo. Após a instalação é criado um grupo de programas 
      denominado ActiveState ActiveTCL, onde estão disponíveis os interpretadores e também o 
      grupo Demos, onde se encontram disponíveis todos os componentes agregados na instalação, 
      com exemplos em tempo de execução e também do código que deverá ser implementado na 
      sua aplicação.
      A partir deste momento, você já terá acesso à todas as funcionalidades do TCL/TK, 
      sem a necessidade de qualquer configuração adicional. As interfaces criadas em TCL/TK 
      já poderão ser visualizadas e processadas.

5 - Compilando o programa cadastro.cob.
5.1 Para compilar e gerar o executável de cadastro.cob digite:

    htcobol -vC cadastro.cob

    Informacoes:
    - O TC suporta a integração com o TCL/TK via call's a um interpretador TCL/TK atraves um 
      wrapper(empacotador) criado pelo Rildo. Esta rotina (initTcl.dll) já se encontra 
      devidamente compilada e presente no diretório C:\TinyCOBOL\bin.

6 - Duvidas e Sugestoes.
    Poste suas duvidas e ou sugestoes para a lista abaixo, sendo que o topico devera ser
    enviado para lista adequada.

6.1 Tinycobol.
    Lista cobol@yahoogrupos.com.br      
    http://br.tinycobol.org
    http://wiki.tinycobol.org

6.2 TCL/TK 
    lista tcl-br@yahoogrupos.com.br
    http://tclbrasil.cipsga.org.br
    http://www.ricardo-jorge.eti.br
    http://www.tcl.tk

7 - Apendice.

7.1 - Agradecimentos.

    - Carlucio Lopes<carsanlo@terra.com.br> que, atraves do seu tutorial, nos
      permitiu dar os primeiros passos com o Tcl/Tk;
    - Rildo Pragana<rildo@pragana.net> pelos primeiros exemplos com Tcl/TK com
      o TinyCobol e pela paciencia em nos ajudar a superar algumas barreiras
      encontradas;
    - John Ousterhout por criar a linguagem TCL e o toolkit grafico TK.
    - Wesley R. Braga, criador do site tclbrasil.cipsga.org.br
    - Ricardo Jorge, grande colaborador da lista tcl-br.
  
7.2  Colaboradores.

    - Danilo Pacheco Martins
    - Fernando Wuthstrack
    - Carlucio Lopes
    - Rildo Pragana
    - Wesley R. Braga
