Neste tópico, falarei sobre adicionar um ícone ao botão, e mostrarei as posições relativas entre ícone e texto.
Carregando o ícone
Para carregar o ícone, basta proceder conforme explicado aqui.
Na declaração da classe:
Em loadIcons():
Lembrando que o ícone deve ser destruído manualmente, em destroyIcons():
Com isso, basta passar o ícone como terceiro argumento do construtor do botão:
Posições relativas entre ícone e texto
A relação de posição entre ícone e menu é definida em FXLabel.h. FXButton é derivado direto de FXLabel. Isso significa que todas as opções deste valem para aquele também. Significa também que toda a discussão a seguir é válida para quando adicionarmos legendas (labels) na nossa interface.
Existem cinco maneiras de posicionar um ícone em relação ao texto, e cada uma delas possui dois sinônimos. As opções são:
Obs.: existem também opções de posicionamento de texto e ícone em relação ao widget, usando opções de justificação, mas isso fica para outro tópico.
ICON_UNDER_TEXT
TEXT_OVER_ICON
Seu valor é 0, o que indica que esta é a opção "padrão". No fim deste tópico, falarei a respeito dessa questão.
Esta opção faz com que o ícone apareça por trás do texto. Exemplo:

ICON_AFTER_TEXT
TEXT_BEFORE_ICON
Desenha o ícone à direita do texto. Exemplo:

ICON_BEFORE_TEXT
TEXT_AFTER_ICON
Desenha o ícone à esquerda do texto. Exemplo:

ICON_ABOVE_TEXT
TEXT_BELOW_ICON
Desenha o ícone acima do texto. Exemplo:

ICON_BELOW_TEXT
TEXT_ABOVE_ICON
Desenha o ícone sob o texto. Exemplo:

Voltando à questão do valor "padrão"
ICON_UNDER_TEXT tem valor 0, o que o torna, teoricamente, a opção padrão.
Para entender essa questão, note que as demais opções podem ser divididas entre posicionamento vertical (ICON_ABOVE_TEXT e ICON_BELOW_TEXT) e posicionamento horizontal (ICON_BEFORE_TEXT e ICON_AFTER_TEXT).
Isso significa que eu posso combinar opções de posicionameto horizontal e vertical. Porém, se eu não especificar um ou outro, a opção padrão será utilizada. Neste caso, é melhor entender a opção padrão não como o nome diz (ícone debaixo (atrás?) do texto), mas que o ícone ficará centralizado naquele eixo que não foi especificado.
Voltando aos exemplos, perceba que ICON_AFTER_TEXT e ICON_BEFORE_TEXT deixam o ícone centralizado na vertical. Da mesma forma, ICON_ABOVE_TEXT e ICON_BELOW_TEXT deixam o ícone centralizado na horizontal. Ainda, a opção ICON_UNDER_TEXT deixa o ícone centralizado em ambos os eixos.
Assim, para o FXButton, temos BUTTON_NORMAL, definido junto com outras opções:
Na declaração do construtor:
Ou seja, para um botão, o padrão é exibir o ícone à esquerda do texto. Como não foi especificado o posicionamento na vertical, fica centralizado.
Espero que essa diferença tenha ficado clara. A distinção está na questão de existir uma opção padrão (que leva o valor 0 exatamente para que não seja necessário informá-la explicitamente) e existir um argumento padrão para o construtor de um widget, que reúne as opções mais comuns, que não necessariamente são as opções padrões.
Veja:

Deixo como exercício.
Até a próxima.
---
Código-fonte para este tutorial.
Carregando o ícone
Para carregar o ícone, basta proceder conforme explicado aqui.
Na declaração da classe:
30 FXIcon *searchIcon;
Em loadIcons():
82 searchIcon = iconSource.loadScaledIconFile("icons/search.gif", 32);
Lembrando que o ícone deve ser destruído manualmente, em destroyIcons():
89 delete searchIcon;
Com isso, basta passar o ícone como terceiro argumento do construtor do botão:
new FXButton(p, "text", searchIcon, ...
Posições relativas entre ícone e texto
A relação de posição entre ícone e menu é definida em FXLabel.h. FXButton é derivado direto de FXLabel. Isso significa que todas as opções deste valem para aquele também. Significa também que toda a discussão a seguir é válida para quando adicionarmos legendas (labels) na nossa interface.
Existem cinco maneiras de posicionar um ícone em relação ao texto, e cada uma delas possui dois sinônimos. As opções são:
enum {
ICON_UNDER_TEXT = 0,
ICON_AFTER_TEXT = 0x00080000,
ICON_BEFORE_TEXT = 0x00100000,
ICON_ABOVE_TEXT = 0x00200000,
ICON_BELOW_TEXT = 0x00400000,
TEXT_OVER_ICON = ICON_UNDER_TEXT,
TEXT_AFTER_ICON = ICON_BEFORE_TEXT,
TEXT_BEFORE_ICON = ICON_AFTER_TEXT,
TEXT_ABOVE_ICON = ICON_BELOW_TEXT,
TEXT_BELOW_ICON = ICON_ABOVE_TEXT
};
Obs.: existem também opções de posicionamento de texto e ícone em relação ao widget, usando opções de justificação, mas isso fica para outro tópico.
ICON_UNDER_TEXT
TEXT_OVER_ICON
Seu valor é 0, o que indica que esta é a opção "padrão". No fim deste tópico, falarei a respeito dessa questão.
Esta opção faz com que o ícone apareça por trás do texto. Exemplo:
25 new FXButton(matrix, "ICON_UNDER_TEXT", searchIcon, NULL, 0,
26 FRAME_RAISED|FRAME_THICK|ICON_UNDER_TEXT);
27
28 new FXButton(matrix, "TEXT_OVER_ICON", searchIcon, NULL, 0,
29 FRAME_RAISED|FRAME_THICK|TEXT_OVER_ICON);

ICON_AFTER_TEXT
TEXT_BEFORE_ICON
Desenha o ícone à direita do texto. Exemplo:
32 new FXButton(matrix, "ICON_AFTER_TEXT", searchIcon, NULL, 0,
33 FRAME_RAISED|FRAME_THICK|ICON_AFTER_TEXT);
34
35 new FXButton(matrix, "TEXT_BEFORE_ICON", searchIcon, NULL, 0,
36 FRAME_RAISED|FRAME_THICK|TEXT_BEFORE_ICON);

ICON_BEFORE_TEXT
TEXT_AFTER_ICON
Desenha o ícone à esquerda do texto. Exemplo:
39 new FXButton(matrix, "ICON_BEFORE_TEXT", searchIcon, NULL, 0,
40 FRAME_RAISED|FRAME_THICK|ICON_BEFORE_TEXT);
41
42 new FXButton(matrix, "TEXT_AFTER_ICON", searchIcon, NULL, 0,
43 FRAME_RAISED|FRAME_THICK|TEXT_AFTER_ICON);

ICON_ABOVE_TEXT
TEXT_BELOW_ICON
Desenha o ícone acima do texto. Exemplo:
46 new FXButton(matrix, "ICON_ABOVE_TEXT", searchIcon, NULL, 0,
47 FRAME_RAISED|FRAME_THICK|ICON_ABOVE_TEXT);
48
49 new FXButton(matrix, "TEXT_BELOW_ICON", searchIcon, NULL, 0,
50 FRAME_RAISED|FRAME_THICK|TEXT_BELOW_ICON);

ICON_BELOW_TEXT
TEXT_ABOVE_ICON
Desenha o ícone sob o texto. Exemplo:
53 new FXButton(matrix, "ICON_BELOW_TEXT", searchIcon, NULL, 0,
54 FRAME_RAISED|FRAME_THICK|ICON_BELOW_TEXT);
55
56 new FXButton(matrix, "TEXT_ABOVE_ICON", searchIcon, NULL, 0,
57 FRAME_RAISED|FRAME_THICK|TEXT_ABOVE_ICON);

Voltando à questão do valor "padrão"
ICON_UNDER_TEXT tem valor 0, o que o torna, teoricamente, a opção padrão.
Para entender essa questão, note que as demais opções podem ser divididas entre posicionamento vertical (ICON_ABOVE_TEXT e ICON_BELOW_TEXT) e posicionamento horizontal (ICON_BEFORE_TEXT e ICON_AFTER_TEXT).
Isso significa que eu posso combinar opções de posicionameto horizontal e vertical. Porém, se eu não especificar um ou outro, a opção padrão será utilizada. Neste caso, é melhor entender a opção padrão não como o nome diz (ícone debaixo (atrás?) do texto), mas que o ícone ficará centralizado naquele eixo que não foi especificado.
Voltando aos exemplos, perceba que ICON_AFTER_TEXT e ICON_BEFORE_TEXT deixam o ícone centralizado na vertical. Da mesma forma, ICON_ABOVE_TEXT e ICON_BELOW_TEXT deixam o ícone centralizado na horizontal. Ainda, a opção ICON_UNDER_TEXT deixa o ícone centralizado em ambos os eixos.
Então por que "padrão", entre aspas? Tem algum detalhe?Sim. Este padrão é considerado neste caso, em que se omite o posicionamento em um dos eixos. Acontece que muitos widgets FOX têm uma opção com o sufixo _NORMAL, que reúnem as opções mais comuns, e são passadas como argumento padrão para o construtor.
Assim, para o FXButton, temos BUTTON_NORMAL, definido junto com outras opções:
BUTTON_NORMAL = (FRAME_RAISED|FRAME_THICK |
JUSTIFY_NORMAL|ICON_BEFORE_TEXT)
Na declaração do construtor:
FXButton(FXComposite* p, ..., FXuint opts=BUTTON_NORMAL, ...
Ou seja, para um botão, o padrão é exibir o ícone à esquerda do texto. Como não foi especificado o posicionamento na vertical, fica centralizado.
Espero que essa diferença tenha ficado clara. A distinção está na questão de existir uma opção padrão (que leva o valor 0 exatamente para que não seja necessário informá-la explicitamente) e existir um argumento padrão para o construtor de um widget, que reúne as opções mais comuns, que não necessariamente são as opções padrões.
E como fica se eu combinar posicionamento vertical e horizontal?
Veja:

Deixo como exercício.
Até a próxima.
---
Código-fonte para este tutorial.
2 comentários:
Algumas dúvidas:
Sei que o fox-toolkit é uma ferramenta para programação C e C++, mas tem como integrar o programa criado com outras tecnologias?
Se for possível, gostaria de ver um post sobre como integrar um programa C++ que usa FOX integrando com alguma outra tecnologia.
Olá,
desde já agradeço o contato.
Na verdade, como o FOX é escrito totalmente em C++, não é possível utilizá-lo em programas escritos em C.
Quanto à integração a outras tecnologias, é possível, sim. Inclusive eu já postei um tópico onde discuto uma simples integração com OpenCV, uma biblioteca de processamento de Imagens e Visão Computacional com que eu trabalho aqui na Universidade.
Pretendo discutir aqui também sobre a integração com OpenGL, e já tive trabalhos de integração com OpenSceneGraph.
Também já trabalhei em projetos envolvendo o toolkit DCMTK, que serve para manipulação de imagens médicas no padrão DICOM.
O FOX Toolkit é apenas para desenho de interface gráfica, portanto não impede o uso de outras tecnologias (excluindo, claro, outros toolkits de interface gráfica).
Quanto à utilização do FOX com outras linguagens, existem bindings para Ruby, Eiffel e Python, mas não posso oferecer suporte a elas.
Espero ter sanado sua dúvida. Sempre que precisar, não hesite em perguntar.
Postar um comentário