Nós não usamos a maioria do poderoso suporte a orientação a objetos do PHP 5 ainda. Vamos fazer uma aplicação que abra um arquivo de texto e mostre o seu conteúdo para você, uma aplicação simples parecida com o bloco de notas. Por favor note que esta é uma aplicação muito muito simples apenas para fins educativos e não tem uma funcionalidade pratica. Aqui esta o código, leia-o, e não seja intimidado pelo seu tamanho. Uma explicação detalhada segue o código:
Exemplo 8.2. Um simples bloco de nota
<?php class Notepad extends GtkWindow { protected $currentFile; protected $buffer; protected $status; protected $context; protected $lastid; function __construct($fileName = null) { parent::__construct(); $mainBox = new GtkVBox(); $textBuff = new GtkTextBuffer(); $textView = new GtkTextView($textBuff); $statusBar= new GtkStatusBar(); $mainBox->pack_start($this->buildMenu(), false, false); $mainBox->pack_start($textView, true, true); $mainBox->pack_start($statusBar, false, false); $this->currentFile = $fileName; $this->buffer = $textBuff; $this->status = $statusBar; $this->connect_simple('destroy', array($this, 'quit')); $this->set_title('Simple Notepad'); $this->maximize(); $this->add($mainBox); $this->show_all(); $this->loadFile(); } function buildMenu() { $menuBar = new GtkMenuBar(); $fileMenu = new GtkMenu(); $menuName = new GtkMenuItem('_File'); $quit = new GtkImageMenuItem('gtk-quit'); $quit->connect_simple('activate', array($this, 'quit')); $quit->connect_simple('enter_notify_event', array($this, 'updateStatus'), 1); $quit->connect_simple('leave_notify_event', array($this, 'updateStatus'), 0); $fileMenu->append($quit); $menuName->set_submenu($fileMenu); $menuBar->add($menuName); return $menuBar; } function loadFile() { if($this->currentFile != null) { $contents = file_get_contents($this->currentFile); $this->buffer->set_text($contents); } } function updateStatus($enter) { if($enter) { $id = $this->status->get_context_id("Message"); $lastMsg = $this->status->push($id, "Quits the Application"); $this->context = $id; $this->lastid = $lastMsg; } else { $this->status->remove($this->context, $this->lastid); } } function quit() { Gtk::main_quit(); } } new Notepad('simple.phpw'); Gtk::main(); ?> |
A estrutura da classe é semelhante ao que nós vimos antes, exceto pela adição de algumas propriedades da classe e funções. Primeiro vamos dar uma olhada no construtor. O construtor leva um parâmetro opcional que o padrão é null. Este parâmetro é (caminho de) o nome do arquivo que você quer abrir. Se você não passar um parâmetro para o construtor, ele simplesmente irá abrir nada.
OK, assim nós primeiro construimos o parent (um GtkWindow) e então criamos alguns widgets que iremos usar. Um GtkVBox para o nosso layout, um GtkTextBuffer e um GtkTextView para mostrar o conteúdo do arquivo e um GtkStatusBar para mostrar algumas mensagens. Nós configuramos o layout e adicionamos os respectivos widgets para o VBox.
Próximo nós definimos as propriedades da classe:
$this->currentFile = $fileName; $this->buffer = $textBuff; $this->status = $statusBar; |
Simplesmente extenda este conceito para os outros widgets também. Basicamente, você precisa definir propriedades de classes para os widgets que você acha que vai precisar em todo o escopo da classe. Ataulamente, propriedades de classes podem ser usadas eficientemente para gardar quaisquer dados que você precise em toda a classe. Um exemplo disso em nossas aplicações é a propriedade currentFile. Isto irá simplesmente guardar o caminho para o arquivo atualmente aberto, ou null se nenhum estiver. Nós podemos então saber o arquivo atualmente aberto em qualquer função da classe. Propriedades de classe tem outros usos também, um dos que eu posso pensar é como marcador. Para a nossa aplicação de bloco de notas, você deve querer adiionar um propriedade chamada saved a qual tem um um valor booleano para indicar quando o arquivo atual foi salvo em disco ou não.
Note que todas as propriedades de classe foram definidas como protected. Isto é simplesmente uma boa pratica de orientação a objetos. Nós não queremos que sejam publicas, mas nós também queremos que qualquer classe que estenda a nossa possa acessa-las.
E finalmente, nós definios o titulo da janela, maximizamos ela, adicionamos o layout e mostramos todos os widgets. E então nós chamamos a função loadFile() para mostrar o conteúdo do nosso arquivo no text buffer que nós tinhamos criado.
Note agora como nós chamamos esta função a partir do construtor:
$mainBox->pack_start($this->buildMenu(), false, false); |
Nesta função, nós apenas criamos a nossa barra de menus, adicionamos um menu file (arquivo) com um único item "Quit" (sair). Vamos dar uma olhada nestas linhas:
$quit->connect_simple('activate', array($this, 'quit')); $quit->connect_simple('enter_notify_event', array($this, 'updateStatus'), 1); $quit->connect_simple('leave_notify_event', array($this, 'updateStatus'), 0); |
$wnd->connect_simple('destroy', array('gtk', 'main_quit')); |
Algumas vezes é possÃvel passar parâmetros para funções para poder usar estes objetos nas funções. Como uma regra, se você tem mais de uma função que usa um objeto em particular, é melhor dedicar uma propriedade de classe para ele; mas se houver apenas uma única função que precise do objeto, ao invés é melhor passar o objeto como parâmetro. Uma ocorrencia comum para esta situação é ao conectar sinais para callbacks. de uma olhada no tutorial sobre sinais e callbacks para mais sobre isto e sobre como passar parâmetros personalizados para os callbacks.
Voltando para a função, nós retornamos o widget superior em nosso menu, a barra de menus, após adicionar a ela o submenu. O construtor então recebe este objeto e adiciona-o ao VBox principal.
O proposito desta função é carregar o conteúdo do arquivo que será aberto e mostra-lo no text view. Primeiro nós conferimos se a propriedade de classe currentFile não é null, e então usamos o metodo set_text() na propriedade de classe buffer.
Esta função serve como callback para os sinais enter-notify-event e leave-notify-event. Aqui nós acessamos a barra de status via a propriedade de classe status e adicionamos/removemos uma mensagem dependendo quando o mouse esta entrando ou saindo do botão de menu "Quit".
Esta é a mais simples função de todas, apenas uma que sai do loop principal do GTK. Você deve imaginar porque nós temos uma função de apenas uma linha chamada "quit" quando nós podiamos conectar os sinais diretamente a main_quit como isto:
$this->connect_simple('destroy', array('Gtk', 'main_quit')); |