Deixar o campo aberto para digitação de datas é muito ágil. Porem algumas vezes é mais viável a utilização de calendário, para a visualização de dias da semana por exemplo. Essa técnica pode ser facilmente adicionada à um GtkTreeview se usado em conjunto de alguns sinais.
Imagem
Exemplo
/** * Seta a codificação do programa */ ini_set("php-gtk.codepage", "UTF-8"); /** * Classe de exemplo * * @name Demo * @author Bruno P. Gonçalves <http: //bruno.pitteli.com.br></http:> * @download <http: //code.google.com/p/fabulafw></http:> */ class Demo { /** * Armazena os widgets necessarios * * @access private * @property array $widgets */ public $widgets = array(); /** * @name __construct() * @return Demo */ public function __construct() { // Cria a janela $this->widgets['frmDemo'] = new GtkWindow(); $this->widgets['frmDemo']->set_size_request(250, 250); $this->widgets['frmDemo']->set_position(Gtk::WIN_POS_CENTER_ALWAYS); $this->widgets['frmDemo']->set_title("Demo"); $this->widgets['frmDemo']->connect("destroy", array($this, "frmDemo_unload")); $vbox = new GtkVBox(); // Cria o modelo $model = new GtkListStore(GObject::TYPE_STRING, GObject::TYPE_STRING); // Creia o treeview $this->widgets['trvTeste'] = new GtkTreeView($model); // Cria a colunas $render = new GtkCellRendererText(); $render->set_property("editable", TRUE); $render->connect("edited", array($this, "trvTeste_onChange"), 0); $column = new GtkTreeViewColumn("Couna 1", $render, "text", 0); $this->widgets['trvTeste']->append_column($column); $render = new GtkCellRendererText(); $render->set_property("editable", TRUE); $render->connect("editing-started", array($this, "trvTeste_onEdit")); $this->widgets['colData'] = new GtkTreeViewColumn("Coluna 2", $render, "text", 1); $this->widgets['trvTeste']->append_column($this->widgets['colData']); // Popula o model $model->append(array("Valor 1", "03/01/2012")); $model->append(array("Valor 2", "02/01/2012")); $model->append(array("Valor 3", "01/01/2012")); // Inicia a aplicação $vbox->pack_start($this->widgets['trvTeste']); $this->widgets['frmDemo']->add($vbox); $this->frmDemo_onload(); } /** * Método do carregamento do formulario * * @name frmDemo_onload() */ public function frmDemo_onload() { // Inicia a aplicação $this->widgets['frmDemo']->show_all(); Gtk::main(); } /** * Método do descarregamento do formulario * * @name frmDemo_unload() */ public function frmDemo_unload() { // Encerra a aplicação Gtk::main_quit(); } /** * Método que inicia a edição da celula * * @name trvTeste_onEdit * @param GtkCellRender $cellRenderer Renderizador da coluna * @param GtkEditable $editable Objeto sendo editado * @param integer $path Linha que foi editada */ function trvTeste_onEdit($cellrenderer, $editable, $path) { $this->__openCalendar($path); $cellrenderer->editing_canceled(); } /** * Método que edita as colunas do trvTeste * * @name trvTeste_onChange * @param GtkCellRender $cellRenderer Renderizador da coluna * @param integer $path Linha que foi editada * @param mixed $value Valor que está sendo adicionado * @param integer $column Numero da coluna editada */ public function trvTeste_onChange($cellRenderer, $path, $value, $column) { // Verifica se foi digitado alguma coisa if(trim($value) == "") { return FALSE; } // Recupera o model do treeview $model = $this->widgets['trvTeste']->get_model(); $iter = $model->get_iter($path); // Seta o valor no treeview $model->set($iter, $column, $value); } /** * Método de abertura do calendario * * @name __openCalendar * @access private */ private function __openCalendar($path) { // Busca as informações da celula $info = $this->widgets['trvTeste']->get_cell_area($path, $this->widgets['colData']); $entryX = $info->x; $entryY = $info->y; // Busca a posição da janela parente $window = $this->widgets['frmDemo']; $win_pos = $window->get_position(); $windowX = $win_pos[0]; $windowY = $win_pos[1]; // Faz o calculo da posicao final $finalX = $entryX + $windowX + 5; $trv_pos = $this->widgets['trvTeste']->window->get_position(); $finalY = $trv_pos[1] + ($info->height * 3) + $entryY + $windowY; // Cria o dialogo para o calendario $dialog = new GtkDialog(NULL, NULL, Gtk::DIALOG_MODAL|Gtk::DIALOG_NO_SEPARATOR); $dialog->set_decorated(FALSE); $dialog->set_uposition($finalX, $finalY); // Cria o calendario e o coloca dentro do dialogo $calendar = new GtkCalendar(); $dialog->vbox->pack_start($calendar, 0, 0); $dialog->action_area->set_size_request(-1, 0); // Busca o dia do entry $model = $this->widgets['trvTeste']->get_model(); $iter = $model[$path]; $text = $model->get_value($iter->iter, 1); if(strlen($text) > 0) { // Separa as datas $date = explode("/", $text); // Marca o dia do entry no calendario $calendar->select_day($date[0]); $calendar->select_month($date[1]-1, $date[2]); } // Faz as conexões do calendario $calendar->connect("day-selected", array($this, "__changedayCalendar"), $dialog, $path); $calendar->connect("focus-out-event", array($this, "__onlostfocusCalendar"), $dialog); $dialog->connect("key-press-event", array($this, "__keypressDialog")); // Mostra o calendario $dialog->show_all(); $dialog->run(); } /** * Método que verifica as teclas pressionadas no dialog * * @access private * @name __keypressDialog * @param GtkDialog $widget Dialogo do calendario * @param GtkEvent $event Informações sobre o evento ocorrido */ function __keypressDialog($widget, $event) { // Verifica se é um ESC if($event->keyval == 65307) { $widget->destroy(); } } /** * Método ao tirar o foco do calendario * * @name __onlostfocusCalendar($widget, $event, $dialog) * @access private * @param GtkCalendar $widget Calendario passado pelo sinal * @param GtkEvents $event Eventos disparados externamente * @param GtkDialog $dialog Container onde está o calendario * @return bool */ public function __onlostfocusCalendar($widget, $event, $dialog) { // Fecha a janela do calendario $dialog->destroy(); return FALSE; } /** * Método disparado ao mudar a data do calendario * * @name __changedayCalendar($widget, $dialog) * @access private * @param GtkCalendar $widget Calendario passado pelo sinal * @param GtkDialog $dialog Container onde está o calendario * @param integer $path Linha editada * @return bool */ public function __changedayCalendar($widget, $dialog, $path) { // Busca o calendario $date = $widget->get_date(); // Formata a data $date[2] = sprintf("%02d", $date[2]); $date[1] = sprintf("%02d", $date[1]+1); $formatedDate = implode("/", array_reverse($date)); // Busca o model $model = $this->widgets['trvTeste']->get_model(); // Coloca a data na celula $this->trvTeste_onChange($this->widgets['colData'], $path, $formatedDate, 1); // Remove o dialog return FALSE; } } /** * Inicia o demo */ new Demo();
Referências
http://gtk.php.net/manual/en/gtk.gtktreeview.php
http://gtk.php.net/manual/en/gtk.gtkcellrenderer.php
http://gtk.php.net/manual/en/gtk.gtkcellrenderertext.php
http://gtk.php.net/manual/en/gtk.gtkdialog.php
http://gtk.php.net/manual/en/gtk.gtkcalendar.php