quarta-feira, 13 de abril de 2011

Gerenciamento de Layout com wxWidgets

Introdução
      Uma aplicação em wxWidgets pode consistir de vários widgets (controles), como botões, caixas de texto, etc dentro de um container (um painel, por exemplo). Estes controles podem ser posicionados dentro do container de duas formas possíveis: com posicionamento absoluto ou através dos sizers.

Posicionamento Absoluto
     O programador especifica o tamanho e posicionamento de cada controle em pixels, desta forma o tamanho dos controles não se altera, ou seja, se eu redimensionar a janela os controles permanecerão na mesma posição e com o mesmo tamanho, além disso a aparência da aplicação pode ficar diferente dependendo da plataforma em que for compilada e executada.

Utilizando Sizers

    Com sizers nós podemos resolver os problemas de posicionamento absoluto. Em wxWidgets nós temos os seguintes sizers: wxBoxSizer, wxStaticBoxSizer, wxGridSizer, wxFlexGridSizer, wxGridBagSizer.

  • wxBoxSizers 
      Com um wxBoxSizer nós podemos colocar vários widgets em linha ou em coluna e podemos colocar um sizer dentro de outro criando assim layouts bem complexos.
      wxBoxSizer(int orientacao)
      wxSizerItem* Add(wxWindow* janela, int proporcao = 0, int flag = 0, int borda = 0)
      A orientação pode ser wxVERTICAL ou wxHORIZONTAL. Para adicionarmos os widgets dentro do wxBoxSizer nós utilizamos o método Add().
     O parâmetro proporcao define a taxa com que os widgets mudam na orientação definida, o parâmetro flag define o comportamento dos widgets dentro de um wxBoxSizer e o parâmetro borda adiciona bordas ao redor dos widgets. Para definirmos as bordas precisamos declarar os lados em que as bordas serão aplicadas no parâmetro flag. Os flags usados podem ser: wxLEFT, wxRIGHT, wxBOTTOM, wxTOP e wxALL. Nós podemos combiná-los através do operador '|' (ou).

  
Abaixo segue em exemplo retirado de:  http://zetcode.com/tutorials/wxwidgetstutorial/layoutmanagement/
    
#include <wx/wx.h>
//border.h

class Border : public wxFrame
{
public:
  Border(const wxString& title);

};
#include "border.h"
//border.cpp
Border::Border(const wxString& title)
       : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 200))
{

  wxColour col1, col2;
  col1.Set(wxT("#4f5049"));
  col2.Set(wxT("#ededed"));

  wxPanel *panel = new wxPanel(this, -1);
  panel->SetBackgroundColour(col1);
  wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);

  wxPanel *midPan = new wxPanel(panel, wxID_ANY);
  midPan->SetBackgroundColour(col2);
  //colocamos uma borda de 20 pixels ao redor do painel midPan
//wxALL aplica a borda ao redor de todo o painel
  //wxEXPAND faz com que a borda ocupe todo o espaço disponível
  vbox->Add(midPan, 1, wxEXPAND | wxALL, 20);
  panel->SetSizer(vbox);

  Centre();
}
#include <wx/wx.h>
//main.h
class MyApp : public wxApp
{
  public:
    virtual bool OnInit();
};
#include "main.h"
#include "border.h"
//main.cpp
IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{

    Border *border = new Border(wxT("Border"));
    border->Show(true);

    return true;
}

  • wxGridSizer
wxGridSizer estabelece os widgets em uma tabela de duas dimensões onde cada célula da tabela tem o mesmo tamanho. 
wxGridSizer(int linhas, int colunas, int vgap, int hgap)
No construtor nós especificamos o número de linhas e colunas de nossa tabela e o espaço horizontal e vertical entre cada célula.
No próximo exemplo nós criaremos o esqueleto de uma cálculadora. 
Este exemplo também foi retirado de: http://zetcode.com/tutorials/wxwidgetstutorial/layoutmanagement/
 
#include <wx/wx.h>
//gridsizer.h

class GridSizer : public wxFrame
{
public:
  GridSizer(const wxString& title);

  wxMenuBar *menubar;
  wxMenu *file;

  wxBoxSizer *sizer;
  wxGridSizer *gs;
  wxTextCtrl *display;

};
#include "gridsizer.h" //gridsizer.cpp
GridSizer::GridSizer(const wxString& title)
       : wxFrame(NULL, -1, title, wxPoint(-1, -1), wxSize(270, 220))
{
  menubar = new wxMenuBar;
  file = new wxMenu;

  SetMenuBar(menubar);

  sizer = new wxBoxSizer(wxVERTICAL);
 
  display = new wxTextCtrl(this, -1, wxT(""), wxPoint(-1, -1),
     wxSize(-1, -1), wxTE_RIGHT);

  sizer->Add(display, 0, wxEXPAND | wxTOP | wxBOTTOM, 4);
  gs = new wxGridSizer(4, 4, 3, 3);

  gs->Add(new wxButton(this, -1, wxT("Cls")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT("Bck")), 0, wxEXPAND);
  gs->Add(new wxStaticText(this, -1, wxT("")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT("Close")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT("7")), 0, wxEXPAND); 
  gs->Add(new wxButton(this, -1, wxT("8")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT("9")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT("/")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT("4")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT("5")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT("6")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT("*")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT("1")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT("2")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT("3")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT("-")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT("0")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT(".")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT("=")), 0, wxEXPAND);
  gs->Add(new wxButton(this, -1, wxT("+")), 0, wxEXPAND);

  sizer->Add(gs, 1, wxEXPAND);
  SetSizer(sizer);
  SetMinSize(wxSize(270, 220));

  Centre();
}
#include <wx/wx.h>
//main.h
class MyApp : public wxApp
{
  public:
    virtual bool OnInit();
};
#include "main.h"
#include "gridsizer.h"
//main.cpp
IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{

    GridSizer *gs = new GridSizer(wxT("GridSizer"));
    gs->Show(true);

    return true;
}
gs->Add(new wxButton(this, -1, wxT("Cls")), 0, wxEXPAND);
Nós chamamos o método Add() várias vezes. Os widgets são colocados dentro da tabela na ordem em que eles são adicionados.
Após o preenchimento de todas as colunas da primeira linha passasse para a segunda linha e assim por diante.
  • wxFlexGridSizer
   Este sizer é muito parecido com o wxGridSizer, todas as células tem a mesma largura em uma coluna e a mesma altura em uma linha, 
mas suas linhas e colunas não precisam ser da mesma largura ou altura.
 wxFlexGridSizer(int linhas, int colunas, int vgap, int hgap)
    No construtor nós especificamos o número de linhas e colunas de nossa tabela e o espaço horizontal e vertical entre cada célula. 
 
 

Nenhum comentário:

Postar um comentário