Todos os gerenciadores de layout do FOX podem ser aninhados, ou seja, podem ser filhos de outros gerenciadores de layout. Essa, na verdade, é uma característica obrigatória em qualquer biblioteca de interface gráfica, pois é isso que permite compor a aparência dos programas. Sem essa capacidade, ficaria quase impossível criar uma interface sofisticada (pense em posicionar cada elemento manualmente, ajustar as bordas de cada seção e outras tarefas tediosas).
Neste tópico, apresentarei um exemplo bem simples (e didático...) desse aninhamento. Farei uma janela semelhante a uma que eu criei para a minha monografia. À esquerda da janela principal, quatro imagens; à direita, uma janela para a exibição 3D. Assim:
Vou logo avisando que vai ficar bem diferente dessa de cima. No final eu explico por que. O objetivo desse tópico é basicamente mostrar o aninhamento dos gerenciadores de layout, utilizando a bagagem que foi adquirida até aqui.
Comecemos, então.
Codificação
O primeiro elemento da janela é uma barra de menu. Aqui tudo será simulado, então utilizarei um HorizontalFrame para a barra:
Os "menus" são simplesmente labels:
Agora vêm os aninhamentos. Na verdade, desde a primeira vez que colocamos um gerenciador de layout, fizemos um aninhamento, já que a própria janela já é um gerenciador de layout, mas aqui isso fica mais explícito.
Primeiramente, um frame horizontal representando o conteúdo da janela:
Eu gosto de definir os filhos imediatamente, formando realmente uma árvore no código (inclusive com indentação); acho que fica mais fácil saber quem é filho de quem, em vez de definir todos os filhos e depois os filhos dos filhos.
Sendo assim, o primeiro filho de contents é um frame vertical:
Dentro dele, tem dois frames horizontais (que ficarão um sobre o outro); dentro de cada um deles, tem dois objetos do tipo FXFrame (que pode ser considerado um espaço vazio), que ficarão um do lado do outro:
O segundo filho de contents também é um FXFrame, apenas para ocupar o espaço:
Resultado
Repetindo, o resultado é totalmente diferente do que foi mostrado acima. Com essa codificação, o que se obtém é isso:
Eu mandei a borda ser desenhada "afundada" justamente para que o aninhamento seja mais visível.
Discussão
O resultado ficou bem diferente do modelo por alguns motivos básicos.
Primeiramente, no modelo eu não utilizei somente FX(Horizontal|Vertical)Frame (não resisti à regex). Existem gerenciadores de layout bem mais propícios para uma interface como aquela.
Segundo, não alterei valores de espaçamento; por isso, dá para ver que as bordas ficam bem distantes umas das outras.
Terceiro, de contents para baixo, todos estão com a opção LAYOUT_FILL. Isso faz que o tamanho final de cada filho seja proporcional ao seu tamanho padrão em relação a seus irmãos. Como do lado esquerdo tem mais filhos, este ficou bem maior que o direito.
E quarto, para o modelo, eu defino explicitamente a largura dos contêineres das imagens (as áreas escuras) de acordo com as imagens carregadas. Tanto que, ao iniciar o programa, eles estão com a largura padrão, que é 1. Vejam:
Conclusão
Este tópico mostrou como é feito o aninhamento de gerenciadores de layout no FOX Toolkit. Espero ter ficado bem claro, pois é algo extremamente útil.
Utilizei nele poucos recursos porque achei melhor me limitar ao que já foi tratado até aqui. Entretanto, tudo o que foi dito aqui vale para qualquer outro gerenciador de layout. O FOX vem inclusive com um exemplo que diz "É claro que eles podem ser aninhados arbitrariamente." Creio que essa frase mostra bem o espírito da coisa.
Só uma observação final: FXFrame, ao contrário do que possa parecer, NÃO é um gerenciador de layout. Muito menos superclasse de FX(Horizontal|Vertical)Frame (como sugere o sufixo). É ele que desenha as bordas dos controles (grossa, fina, levantada, abaixada etc.).
FXFrame pode ser utilizado apenas como um "guarda-lugar" (placeholder), como foi feito aqui. Entretanto, é mais utilizado como classe-base para controles simples; por exemplo, FXLabel é derivado direto de FXFrame (e FXButton é derivado direto de FXLabel).
Um abraço e até a próxima.
---
Código-fonte para este tutorial.
Neste tópico, apresentarei um exemplo bem simples (e didático...) desse aninhamento. Farei uma janela semelhante a uma que eu criei para a minha monografia. À esquerda da janela principal, quatro imagens; à direita, uma janela para a exibição 3D. Assim:
Vou logo avisando que vai ficar bem diferente dessa de cima. No final eu explico por que. O objetivo desse tópico é basicamente mostrar o aninhamento dos gerenciadores de layout, utilizando a bagagem que foi adquirida até aqui.
Comecemos, então.
Codificação
O primeiro elemento da janela é uma barra de menu. Aqui tudo será simulado, então utilizarei um HorizontalFrame para a barra:
23 FXHorizontalFrame *menuBar = new FXHorizontalFrame(this,
24 LAYOUT_SIDE_TOP|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH);
Os "menus" são simplesmente labels:
26 /* Menu Arquivo */
27 new FXLabel(menuBar, "&Arquivo");
28
29 /* Menu Imagens */
30 new FXLabel(menuBar, "&Imagens");
Agora vêm os aninhamentos. Na verdade, desde a primeira vez que colocamos um gerenciador de layout, fizemos um aninhamento, já que a própria janela já é um gerenciador de layout, mas aqui isso fica mais explícito.
Primeiramente, um frame horizontal representando o conteúdo da janela:
32 FXHorizontalFrame *contents = new FXHorizontalFrame(this,
LAYOUT_SIDE_TOP|LAYOUT_FILL|FRAME_NORMAL);
Eu gosto de definir os filhos imediatamente, formando realmente uma árvore no código (inclusive com indentação); acho que fica mais fácil saber quem é filho de quem, em vez de definir todos os filhos e depois os filhos dos filhos.
Sendo assim, o primeiro filho de contents é um frame vertical:
33 FXVerticalFrame *frameExam = new FXVerticalFrame(contents,
LAYOUT_FILL|FRAME_NORMAL);
Dentro dele, tem dois frames horizontais (que ficarão um sobre o outro); dentro de cada um deles, tem dois objetos do tipo FXFrame (que pode ser considerado um espaço vazio), que ficarão um do lado do outro:
34 FXHorizontalFrame *ccFrame = new FXHorizontalFrame(frameExam,
LAYOUT_FILL|FRAME_NORMAL);
35 new FXFrame(ccFrame, LAYOUT_FILL|FRAME_NORMAL);
36 new FXFrame(ccFrame, LAYOUT_FILL|FRAME_NORMAL);
37
38 FXHorizontalFrame *mloFrame = new FXHorizontalFrame(frameExam,
LAYOUT_FILL|FRAME_NORMAL);
39 new FXFrame(mloFrame, LAYOUT_FILL|FRAME_NORMAL);
40 new FXFrame(mloFrame, LAYOUT_FILL|FRAME_NORMAL);
O segundo filho de contents também é um FXFrame, apenas para ocupar o espaço:
42 new FXFrame(contents, LAYOUT_FILL|FRAME_NORMAL);
Resultado
Repetindo, o resultado é totalmente diferente do que foi mostrado acima. Com essa codificação, o que se obtém é isso:
Eu mandei a borda ser desenhada "afundada" justamente para que o aninhamento seja mais visível.
Discussão
O resultado ficou bem diferente do modelo por alguns motivos básicos.
Primeiramente, no modelo eu não utilizei somente FX(Horizontal|Vertical)Frame (não resisti à regex). Existem gerenciadores de layout bem mais propícios para uma interface como aquela.
Segundo, não alterei valores de espaçamento; por isso, dá para ver que as bordas ficam bem distantes umas das outras.
Terceiro, de contents para baixo, todos estão com a opção LAYOUT_FILL. Isso faz que o tamanho final de cada filho seja proporcional ao seu tamanho padrão em relação a seus irmãos. Como do lado esquerdo tem mais filhos, este ficou bem maior que o direito.
E quarto, para o modelo, eu defino explicitamente a largura dos contêineres das imagens (as áreas escuras) de acordo com as imagens carregadas. Tanto que, ao iniciar o programa, eles estão com a largura padrão, que é 1. Vejam:
Conclusão
Este tópico mostrou como é feito o aninhamento de gerenciadores de layout no FOX Toolkit. Espero ter ficado bem claro, pois é algo extremamente útil.
Utilizei nele poucos recursos porque achei melhor me limitar ao que já foi tratado até aqui. Entretanto, tudo o que foi dito aqui vale para qualquer outro gerenciador de layout. O FOX vem inclusive com um exemplo que diz "É claro que eles podem ser aninhados arbitrariamente." Creio que essa frase mostra bem o espírito da coisa.
Só uma observação final: FXFrame, ao contrário do que possa parecer, NÃO é um gerenciador de layout. Muito menos superclasse de FX(Horizontal|Vertical)Frame (como sugere o sufixo). É ele que desenha as bordas dos controles (grossa, fina, levantada, abaixada etc.).
FXFrame pode ser utilizado apenas como um "guarda-lugar" (placeholder), como foi feito aqui. Entretanto, é mais utilizado como classe-base para controles simples; por exemplo, FXLabel é derivado direto de FXFrame (e FXButton é derivado direto de FXLabel).
Um abraço e até a próxima.
---
Código-fonte para este tutorial.
2 comentários:
O código-fonte pode não estar disponível: devido a problemas de conexão, não consegui colocá-los no servidor.
Deixei o link apenas para não precisar editar o tópico; assim que possível, disponibilizarei o fonte.
Código-fonte já disponível
Postar um comentário