Mostrando postagens com marcador referência. Mostrar todas as postagens
Mostrando postagens com marcador referência. Mostrar todas as postagens

sexta-feira, 24 de abril de 2009

Widgets

Este tópico discute um pequeno detalhe a respeito do construtor dos widgets FOX. Serve para mostrar um dos pontos fortes do FOX Toolkit, a consistência, e também alguns aspectos que serão mostrados aqui servirão para tópicos futuros.

Bom, os widgets FOX têm um construtor similar:
FXWidget(FXComposite *p,
...
FXObject* tgt,
FXSelector sel,
FXuint opts,
FXint x, FXint y,
FXint w, FXint h,
FXint pl, FXint pr,
FXint pt, FXint pb
FXint hs, FXint vs
);

Alguns dele já foram explicados em tópicos anteriores, mas vou falar de todos aqui.


FXComposite *p

O componente que será o pai do widget criado. Serve para montar a hierarquia dos objetos FOX sem a necessidade guardar em um ponteiro e chamar algo do tipo p->add() (sem querer falar mal de outras linguagens...).

Normalmente é um gerenciador de layout.


Parâmetros específicos

Depois do dono do widget, vêm alguns parâmetros específicos. Por exemplo, para um botão (FXButton) esses parâmetros são o texto do botão e o ícone.

Naturalmente, nem todos os widgets terão parâmetros específicos, e a quantidade varia de widget para widget. Mas eles sempre vêm depois do dono e antes do alvo dos eventos (exceto para gerenciadores de layout).


FXObject *tgt

FXObject é o topo da hierarquia de classes do FOX Toolkit. Esse parâmetro indica que objeto irá receber os eventos disparados.

Se esse parâmetro é um FXObject, então qualquer objeto FOX pode receber eventos?

Sim. Não só receber como também enviar.

E só aproveitando o ensejo, aqui outra grande característica do FOX se revela: a capacidade de conectar os objetos entre si. Aqui essa conexão é estabelecida.


FXSelector sel

Além do alvo do evento, é preciso dizer qual é a mensagem que este widget envia. FXSelector nada mais é que um inteiro sem sinal.

Quando falarmos de tratamento de evento, esses dois parâmetros serão discutidos em mais detalhes.

Obs.: não estão presentes em gerenciadores de layout. Simplesmente porque eles não enviam eventos que o usuário queira tratar por conta própria.


FXuint opts

As opções do widget.

Alguns widgets possuem opções específicas. Por exemplo, um botão tem a opção BUTTON_TOOLBAR (entre outras, naturalmente) que faz com que ele tenha aparência achatada, levantando as bordas ao se passar com o mouse por cima (como o próprio nome diz, um botão da barra de ferramentas).

Aqui são passadas também opções de borda e de layout. No tutorial sobre criar um botão (aqui), eu criei um botão normal (ou seja, com borda levantada, grossa, com o texto centralizado e o ícone antes do texto) e que se expande pela janela inteira (uma opção de layout).

Todas essas opções são definidas por meio de enumerações e podem ser combinadas com o operador OU sobre bits ( | ).


FXint x, FXint y

Posição. O único detalhe é que essas coordenadas são em relação à janela pai (mãe?). Mas como os gerenciadores de layout se encarregam de posicionar seus filhos, raramente é necessário especificá-los manualmente.


FXint w, FXint h

Largura e altura do widget. Novamente, isso é controlado pelos gerenciadores de layout. Mas é mais comum precisar controlar o tamanho que a posição.

Normalmente não é necessário porque a maioria dos widgets sabe seu tamanho mínimo: um botão, por padrão, sempre vai ter um tamanho suficiente para exibir seu texto e ícone. Entretanto, alguns widgets não têm um tamanho mínimo: um FXCanvas, por exemplo, não tem nada dentro dele para calcular seu tamanho mínimo, então tem que dizer o tamanho dele (ou deixar que o gerenciador de layout o diga).

FXint pl, FXint pr, FXint pt, FXint pb

Bem, esses parâmetros servem para informar a quantidade de espaço entre sua borda e outros widgets. Se for um gerenciador de layout, define o espaço entre sua borda interna e os widgets (conforme já explicado aqui). Se for um widget folha (ou seja, não recebe nenhum filho na hierarquia), indica o espaço entre sua borda externa e outros widgets, conforme a figura a seguir:


Esses aqui é que são raros de especificar. Os valores padrões que eles apresentam dão praticamente sempre bons resultados.


FXint hs, FXint vs

Estes só estão disponíveis para gerenciadores de layout. Informam o espaço entre os seus filhos; também foi explicado aqui. E seus valores padrões também dão um resultado agradável.

quarta-feira, 15 de abril de 2009

FXTopWindow: Decorações e Posicionamento de Janelas

Quando falei sobre criar a janela principal (aqui), citei alguns aspectos relativos às decorações da janela e seu posicionamento, informando que isto era definido em FXTopWindow.h, onde está definida a superclasse direta de FXMainWindow.

Falarei agora especificamente desses dois assuntos.

Decorações

As decorações são itens "extras" que o seu decorador de janelas acrescenta. São as bordas da janela, barra de título, botões de minimizar, maximizar, fechar, menu da janela etc. FXTopWindow.h define a seguinte enumeração:

enum {
DECOR_NONE = 0,
DECOR_TITLE = 0x00020000,
DECOR_MINIMIZE = 0x00040000,
DECOR_MAXIMIZE = 0x00080000,
DECOR_CLOSE = 0x00100000,
DECOR_BORDER = 0x00200000,
DECOR_SHRINKABLE = 0x00400000,
DECOR_STRETCHABLE = 0x00800000,
DECOR_RESIZE = DECOR_SHRINKABLE|DECOR_STRETCHABLE,
DECOR_MENU = 0x01000000,
DECOR_ALL = (DECOR_TITLE |
DECOR_MINIMIZE |
DECOR_MAXIMIZE |
DECOR_CLOSE |
DECOR_BORDER |
DECOR_SHRINKABLE |
DECOR_STRETCHABLE |
DECOR_MENU
)
};

Apesar de serem bem intuitivos os nomes, vou explicá-los:
  • DECOR_NONE: Janela sem bordas, sem nada, só com o conteúdo. Se parecer inútil, pense em uma janela em modo tela cheia.
  • DECOR_TITLE: Título da janela.
  • DECOR_MINIMIZE: Adiciona a capacidade de minimizar a janela.
  • DECOR_MAXIMIZE: Adiciona a capacidade de maximizar a janela.
  • DECOR_CLOSE: Adiciona a capacidade de fechar a janela.
  • DECOR_BORDER: Adiciona bordas à janela.
  • DECOR_SHRINKABLE: Possibilita diminuir o tamanho da janela.
  • DECOR_STRETCHABLE: Possibilita aumentar o tamanho da janela.
  • DECOR_RESIZE: Permite aumentar ou diminuir a janela. Perceba que é apenas uma combinação das duas anteriores para facilitar.
  • DECOR_MENU: Habilita o menu da janela.
  • DECOR_ALL: Já conhecido, habilita todo mundo.

Agora a pergunta: se é tão intuitivo, porque explicar cada um? Simples. Essas são apenas sugestões para o decorador de janelas. Não são regras.

Isso quer dizer que, se o decorador achar melhor desenhar um item que você não especificou, ele desenha. Por isso eu não falei "Desenha isso", "Desenha aquilo", mas sim "Adiciona a capacidade", "Habilita". Por exemplo, para exibir o botão de fechar, tem que ter a barra de título (e com certeza as bordas vêm de brinde). Acontece também de se especificarem somente os botões de minimizar e fechar, mas o de maximizar aparece junto, desabilitado.

O que eu quero dizer é que cada decorador tem suas regras próprias, e que essas são apenas sugestões. Mas tenha certeza que o que você especificar ele faz. E se não especificar, também não faz; ou seja, se você não quer que a janela aumente de tamanho nem maximize, ela não irá, embora o botão de maximizar esteja lá (desabilitado, claro).

Não quero dizer, por outro lado, que você deva confiar sempre nos itens que vêm de "brinde". Especifique sempre os que você quer ter certeza que estejam disponíveis.

Posicionamento

Para mostrar a janela, chamei o método show(), passando PLACEMENT_SCREEN como parâmetro, exibindo no meio da tela. As opções de posicionamento são:
enum {
PLACEMENT_DEFAULT,
PLACEMENT_VISIBLE,
PLACEMENT_CURSOR,
PLACEMENT_OWNER,
PLACEMENT_SCREEN,
PLACEMENT_MAXIMIZED
};

  • PLACEMENT_DEFAULT: No tamanho e posição que foram especificados no construtor.
  • PLACEMENT_VISIBLE: Posiciona a janela para ficar totalmente visível. Confesso que nunca usei...
  • PLACEMENT_CURSOR: Posiciona onde está o cursor do mouse.
  • PLACEMENT_OWNER: Posiciona no centro da janela dona desta. Quando adicionarmos mais janelas, esta opção será utilizada.
  • PLACEMENT_SCREEN: Já conhecido, posiciona no centro da tela.
  • PLACEMENT_MAXIMIZED: Deixa a janela do tamanho da tela. Mas tem uma ressalva.

O PLACEMENT_MAXIMIZED realmente deixa a janela do tamanho da tela. Porém, dependendo do decorador (sempre ele...) as bordas vão todas embora. Dos que eu já usei (foram só três, mas tudo bem), só o Emerald (sempre ele...) preservou as bordas, deixando a janela do jeito que se imagina que uma janela maximizada deva ser. O decorador do Windows (não sei o nome) e o gtk-window-decorator (decorador padrão do GNOME) sumiram com as bordas.

E se eu quiser que a janela já inicie maximizada, com borda e tudo?

Chame maximize() em vez de show().

segunda-feira, 13 de abril de 2009

FXMainWindow

Já que nosso último tutorial foi sobre criar uma janela vazia, usando FXMainWindow, falarei agora especificamente sobre essa classe.

Descrição
A MainWindow é normalmente a janela central de uma aplicação. Aplicações podem ter qualquer número de janelas principais.

Quando uma MainWindow é fechada, ela envia uma mensagem SEL_CLOSE para o seu alvo; o alvo deve retornar 0 se não houver nenhuma objeção contra o fechamento, e 1 caso contrário.

Depois que a mensagem SEL_CLOSE for enviada e nenhuma objeção for levantada, a janela principal deletará a si mesma.

Declaração

1 class FXAPI FXMainWindow : public FXTopWindow {
2 FXDECLARE(FXMainWindow)
3 protected:
4 FXMainWindow(){}
5 private:
6 FXMainWindow(const FXMainWindow&);
7 FXMainWindow &operator=(const FXMainWindow&);
8 public:
9
10 /// Constrói uma janela principal
11 FXMainWindow(FXApp* a, const FXString& name,
12 FXIcon *ic = NULL, FXIcon *mi = NULL,
13 FXuint opts = DECOR_ALL,
14 FXint x = 0, FXint y = 0,
15 FXint w = 0, FXint h = 0,
16 FXint pl = 0, FXint pr = 0,
17 FXint pt = 0, FXint pb = 0,
18 FXint hs = 0, FXint vs = 0
19 );
20
21 /// Cria os recursos do servidor (server-side)
22 virtual void create();
23
24 /// Destrutor
25 virtual ~FXMainWindow();
26 };

Sim, ela é só isso.

Discussão

1: A classe FXMainWindow é derivada de FXTopWindow. Por isso ela é pequena desse jeito, toda a funcionalidade dela é herdada das superclasses. E a hierarquia não é pequena:



Obs.: Em tópicos deste tipo, tratarei de apenas uma classe, ou seja, vou me limitar ao que a declaração da classe apresenta.

11-19: Construtor. Recebe 15 parâmetros:
  • FXApp *a - Ponteiro para a aplicação.
  • FXString &name - Título da janela.
  • FXIcon *ic, FXIcon *mi - Ícones da janela.
    • Ícone grande, que aparece quando se troca de janela com Alt+Tab
    • Ícone pequeno, que aparece no canto superior esquerdo da janela

  • FXuint opts - Opções da janela.
    Essas opções referem-se às decorações da janela, e são definidas em FXTopWindow.h. Chegaremos lá.

  • FXint x, FXint y - Posição inicial da janela.
  • FXint w, FXint h - Largura e altura da janela.
  • FXint pl, FXint pr, FXint pt, FXint pb - Espaçamento entre os componentes e a borda da janela.
    Uma MainWindow é um gerenciador de layout (layout manager), portanto aceita esses parâmetros. Quando falarmos de gerenciadores de layout, explicarei melhor.

  • FXint hs, FXint vs - Espaçamento entre um componente e outro.
    Idem.

Percebam que apenas a aplicação e o título da janela são obrigatórios. Todos os outros parâmetros têm valores default, ou seja, podem ser omitidos. Outra vantagem do FOX Toolkit: os parâmetros default asseguram um layout agradável aos olhos.

Observações
  1. A descrição da classe foi retirada da própria documentação de referência.
  2. O gráfico de herança foi desenhado com o programa Dia.

Links