quarta-feira, fevereiro 07, 2007

Curso de wxWidgets, post 13: Formatando texto

Para finalizar o editor de textos, vamos adicionar formatação a ele. Para isto, irei usar uma função que já vimos no curso: wxGetFontFromUser().

Primeiro, vamos incluir o cabeçalho da função:

#include <wx/fontdlg.h>


Vamos também criar um novo método para a formatação. Este método irá se chamar MeuFrame::Formatar(). Vamos declarar a nova função na definição da classe:


class MeuFrame: public wxFrame
{
...
private:
...
void Formatar(void);
}


E agora, implementemos o método:


// Formatação
void MeuFrame::Formatar(void)
{
long inicio, fim;
wxTextAttr attr;
wxFont font;

// Obtém a formatação atual (não suportado em todas as plataformas)
txt_file->GetSelection(&inicio, &fim);
txt_file->GetStyle(inicio, attr);
font = attr.GetFont();

// Altera a formatação
font = wxGetFontFromUser(this, font);
attr.SetFont(font);
txt_file->SetStyle(inicio, fim, attr); // Aplica o estilo ao texto
}


Primeiro, o método tenta obter a formatação atual do texto selecionado (wxTextCtrl::GetStyle() não é suportado em todas as plataformas, testei no Linux e não funcionou). Após obter a formatação, iremos utilizá-la em wxGetFontFromUser() para inicializar os valores da janela, assim, sempre a janela de formatação for aberta, ela estará configurada com a formatação atual.

Em seguida, wxGetFontFromUser() retorna a nova formatação e podemos aplicá-la ao texto selecionado.

Agora devemos criar um botão na barra de ferramentas para este método. Vamos adicionar uma ID para este botão:


// IDs
enum
{
ID_TBAR_NEW,
ID_TBAR_LOAD,
ID_TBAR_SAVE,
ID_TBAR_FORMAT, // Este foi adicionado
ID_TBAR_ABOUT
};


E criamos o novo botão no construtor de MeuFrame:


tbar->AddTool(ID_TBAR_FORMAT, wxString(wxT("Formatar")), \
wxBitmap(wxT("/usr/share/pixmaps/gedit-icon.png"), wxBITMAP_TYPE_PNG));


Pronto! Está feito. :)



Próximo passo

O editor de textos pára por aqui. Estou querendo falar sobre sockets no próximo post, mas precisarei elaborar um texto maior, pois tem bastante coisa pra explicar. Se alguém quiser aprender algo específico do wxWidgets, postem nos comentários. Assim vocês me ajudam a escolher o próximo assunto. :)

Como sempre faço, o código-fonte completo está abaixo:

/* A Casa de Just - http://jpjust.blogspot.com
* Curso de wxWidgets: Um editor de textos
*
* O objetivo deste código-fonte é demonstrar diversas classes
* ensinadas no curso de wxWidgets do blog "A Casa de Just".
*
* As aulas do curso de wxWidgets podem ser encontradas em forma
* de posts no blog: http://jpjust.blogspot.com
*
* Copyright (c) João Paulo Just <jpjust@justsoft.com.br>
* A Casa de Just - http://jpjust.blogspot.com
* 07 de fevereiro de 2007, 20:24, Ilhéus, BA, Brasil.
*/

#include <wx/wx.h>
#include <wx/fontdlg.h>

// IDs
enum
{
ID_TBAR_NEW,
ID_TBAR_LOAD,
ID_TBAR_SAVE,
ID_TBAR_FORMAT,
ID_TBAR_ABOUT
};

// Classe do programa
class MeuPrograma: public wxApp
{
public:
// Método principal
virtual bool OnInit(void);
};

// Classe do frame
class MeuFrame: public wxFrame
{
public:
// Construtor
MeuFrame(void);

// Eventos
void OnToolBarClick(wxCommandEvent &event);

// Métodos auxiliares
void Novo(void);
void Abrir(void);
void Salvar(void);
void Formatar(void);
void Sobre(void);

DECLARE_EVENT_TABLE()

private:
// Widgets do frame
wxTextCtrl *txt_file;
wxToolBar *tbar;
wxStatusBar *stbar;
};

// Inicialização do programa
bool MeuPrograma::OnInit(void)
{
wxInitAllImageHandlers(); // Inicia todos os hadlers de imagens do wxBitmap

MeuFrame *frame = new MeuFrame();
frame->Show();
SetTopWindow(frame);
return true;
}

// Tabela de eventos
BEGIN_EVENT_TABLE(MeuFrame, wxFrame)
EVT_TOOL_RANGE(ID_TBAR_NEW, ID_TBAR_ABOUT, MeuFrame::OnToolBarClick)
END_EVENT_TABLE()

// Construtor do frame
MeuFrame::MeuFrame(void)
:wxFrame(NULL, wxID_ANY, wxT("Editor de textos - http://jpjust.blogspot.com"))
{
// Sizer e widgets
wxBoxSizer *sizer_v = new wxBoxSizer(wxVERTICAL);

txt_file = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);

// Barra de ferramentas
tbar = new wxToolBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTB_TEXT);

tbar->AddTool(ID_TBAR_NEW, wxString(wxT("Novo")), \
wxBitmap(wxT("/usr/share/pixmaps/gedit-icon.png"), wxBITMAP_TYPE_PNG));

tbar->AddTool(ID_TBAR_LOAD, wxString(wxT("Abrir")), \
wxBitmap(wxT("/usr/share/pixmaps/gnome-folder.png"), wxBITMAP_TYPE_PNG));

tbar->AddTool(ID_TBAR_SAVE, wxString(wxT("Salvar")), \
wxBitmap(wxT("/usr/share/pixmaps/gnome-cd.png"), wxBITMAP_TYPE_PNG));

tbar->AddSeparator();

tbar->AddTool(ID_TBAR_FORMAT, wxString(wxT("Formatar")), \
wxBitmap(wxT("/usr/share/pixmaps/gedit-icon.png"), wxBITMAP_TYPE_PNG));

tbar->AddSeparator();

tbar->AddTool(ID_TBAR_ABOUT, wxString(wxT("Sobre")), \
wxBitmap(wxT("/usr/share/pixmaps/gnome-info.png"), wxBITMAP_TYPE_PNG));

tbar->Realize();

// Barra de status
stbar = new wxStatusBar(this);
stbar->SetStatusText(wxT("Sem título"));

// Posicionamento
sizer_v->Add(txt_file, 1, wxALL | wxEXPAND, 5);

SetSizerAndFit(sizer_v);

// Insere a barra de ferramentas e a barra de status
SetToolBar(tbar);
SetStatusBar(stbar);
}

// Limpa a tela para um novo arquivo
void MeuFrame::Novo(void)
{
int msg = wxMessageBox(wxT("Deseja salvar o arquivo atual antes de criar um novo?"), \
wxT("Novo arquivo"), wxYES_NO | wxCANCEL);

if (msg == wxYES) // Salva
Salvar();
else if (msg == wxCANCEL) // Cancela a operação
return;

// Cria um novo arquivo
txt_file->Clear();
stbar->SetStatusText(wxT("Sem título"));
}

// Abre um arquivo
void MeuFrame::Abrir(void)
{
wxString Filename;

// Abre diálogo de arquivo
Filename = wxFileSelector(wxT("Selecione o arquivo"),
wxEmptyString, wxEmptyString, wxEmptyString,
wxT("*.txt"), wxOPEN | wxFILE_MUST_EXIST);

// Se arquivo inválido, sai do método
if (Filename == wxEmptyString)
return;

txt_file->LoadFile(Filename);

// Atualiza o nome
stbar->SetStatusText(Filename);
}

// Salva o arquivo aberto
void MeuFrame::Salvar(void)
{
wxString Filename;

// Abre diálogo de arquivo
Filename = wxFileSelector(wxT("Selecione o arquivo"),
wxEmptyString, wxEmptyString, wxEmptyString,
wxT("*.txt"), wxSAVE | wxOVERWRITE_PROMPT);

// Se arquivo inválido, sai do método
if (Filename == wxEmptyString)
return;

txt_file->SaveFile(Filename);

// Atualiza o nome do arquivo
stbar->SetStatusText(Filename);
}

// Formatação
void MeuFrame::Formatar(void)
{
long inicio, fim;
wxTextAttr attr;
wxFont font;

// Obtém a formatação atual (não suportado em todas as plataformas)
txt_file->GetSelection(&inicio, &fim);
txt_file->GetStyle(inicio, attr);
font = attr.GetFont();

// Altera a formatação
font = wxGetFontFromUser(this, font);
attr.SetFont(font);
txt_file->SetStyle(inicio, fim, attr); // Aplica o estilo ao texto
}

// Janela "Sobre"
void MeuFrame::Sobre(void)
{
wxMessageBox(wxT("Curso de wxWidgets\n\nhttp://jpjust.blogspot.com"), wxT("Sobre"), wxICON_INFORMATION);
}

// Método para a barra de ferramentas
void MeuFrame::OnToolBarClick(wxCommandEvent &event)
{
switch (event.GetId())
{
case ID_TBAR_NEW:
Novo();
break;

case ID_TBAR_LOAD:
Abrir();
break;

case ID_TBAR_SAVE:
Salvar();
break;

case ID_TBAR_FORMAT:
Format();
break;
}
}

IMPLEMENT_APP(MeuPrograma)

7 comentários:

Anônimo disse...

ola, bom eu estou adorando este curso, e gostaria de pedir, se você puder, uma aula, ou uma pequena explicação de utilização de banco de dados com o wxWidgets, desde ja agredeço.

Unknown disse...

Olá Fernando.

Esta é uma boa idéia. Se não me engano, foi você que me mandou um e-mail uma vez pedindo isso. :)

Precisarei estudar como usar banco de dados no wx, nunca fiz isso antes :P Irei dar uma olhada nisso nessa semana pra fazer o próximo post. Se você já tiver alguma informação boa, pode mandar.

Fernando Gimenes Xavier disse...

A blz cara, obrigado, bom vou ver o que posso aprender também, e não fui eu quem enviou email, bom falou cara.

Anônimo disse...

para banco de dados, eu usei o sqlapi e consegui fazer tudo numa boa.. É uma biblioteca paga, mas muito boa...
www.sqlapi.com

Unknown disse...

Olá Meira.

O wx roda muito bem no Linux e não é pesado. O wxGTK roda em cima do GTK+ sim, ele usa as funções do GTK pra fazer todo o serviço de GUIs.

Tem também o wxX11, que usa o X Window System pra desenhas os gráficos, caso você não queira usar o GTK+. E ainda existe um port para Motif.

Em qualquer um dos três casos, você só precisa escrever o código em wx. Então, você pode compilar três versões diferentes da biblioteca do wx, em wxGTK, wxX11 e wxMotif. Aí é só compilar seu programa com cada uma delas e ver como fica. :)

Gustavo Meira disse...

agradeço a atenção :)
tomara que a comunidade wx creça muito
abraço

Rafael Souza e Silva disse...

Olá Just, estou trabalhando agora com desenvolvimento de software e estou usando o wxWidgets e o Crystal Space, e eu gostaria de fazer uma pergunta.
Na faculdade estou aprendendo java e quando uso o eclipse om java eu tenho o recurso de autocomplete. Gostaria de saber se tem algum jeito de colocar o autocomplete quando eu estiver programando usando Crystal Space ou wxWidgets.
Estou usando o seu curso para aprender wxWidgets e você já deve ter se cansado de ouvir que é muito bom, mas não custa nada falar de novo. Parabéns pela sua iniciativa.
Atenciosamente, Mamangava.