C++ - Gerenciando layout em FLTK

Introdução
O FLTK utiliza um sistema simples, porém versátil para redimensionar interfaces.
Aplicação inicial
- Para demonstrar o gerenciamento do layout criei uma aplicação composta de 9 botões com labels de 1 até 9.
- Note que eu criei os botões totalmente fora de ordem: 5, 2, 4, 8, 6, 1, 3, 7 e 9. Isto não importa para o layout.
- Todos os botões são filhos da janela principal.
Arquivo 01.fl
# data file for the Fltk User Interface Designer (fluid)
version 1.0304
header_name {.h}
code_name {.cxx}
Function {} {open
} {
Fl_Window {} {
label 01 open selected
xywh {122 262 420 180} type Double visible
} {
Fl_Button {} {
label 5
xywh {140 60 140 60}
}
Fl_Button {} {
label 2
xywh {140 0 140 60}
}
Fl_Button {} {
label 4
xywh {0 60 140 60}
}
Fl_Button {} {
label 8
xywh {140 120 140 60}
}
Fl_Button {} {
label 6
xywh {280 60 140 60}
}
Fl_Button {} {
label 1
xywh {0 0 140 60}
}
Fl_Button {} {
label 3
xywh {280 0 140 60}
}
Fl_Button {} {
label 7
xywh {0 120 140 60}
}
Fl_Button {} {
label 9
xywh {280 120 140 60}
}
}
}
Arquivo Makefile
Para realizar a compilação dos programas crie o seguinte Makefile
:
# ----------------------------------------------------------------------
# Copyright (C) 2022-2023 Geraldo Ribeiro <geraldo@intmain.io>
# ----------------------------------------------------------------------
PROGRAMS=01 02 03 04
GENERATED=$(addsuffix .h, $(PROGRAMS)) $(addsuffix .cxx, $(PROGRAMS))
CXXFLAGS+=-std=c++17
CXXFLAGS+=`fltk-config --cxxflags`
LDFLAGS+=`fltk-config --ldflags`
# Geração de código
%.cxx: %.fl
fluid -c $^
# Opção de compilação 1
%: %.cxx
fltk-config --compile $^
# Opção de compilação 2
#%: %.cxx
# $(CXX) $(LDFLAGS) $^ -o $@ $(LDFLAGS)
all: $(PROGRAMS)
clean:
rm -f $(PROGRAMS) $(GENERATED)
Geração de código
Para gerar o código C++ (.cxx
) a partir do Fluid (.fl
) basta digitar make
que o código é gerado e compilado:
make
fluid -c 01.fl
fltk-config --compile 01.cxx
Arquivo gerado 01.cxx
// generated by Fast Light User Interface Designer (fluid) version 1.0304
#include "01.h"
int main(int argc, char **argv) {
Fl_Double_Window* w;
{ Fl_Double_Window* o = new Fl_Double_Window(420, 180, "01");
w = o; if (w) {/* empty */}
{ new Fl_Button(140, 60, 140, 60, "5");
} // Fl_Button* o
{ new Fl_Button(140, 0, 140, 60, "2");
} // Fl_Button* o
{ new Fl_Button(0, 60, 140, 60, "4");
} // Fl_Button* o
{ new Fl_Button(140, 120, 140, 60, "8");
} // Fl_Button* o
{ new Fl_Button(280, 60, 140, 60, "6");
} // Fl_Button* o
{ new Fl_Button(0, 0, 140, 60, "1");
} // Fl_Button* o
{ new Fl_Button(280, 0, 140, 60, "3");
} // Fl_Button* o
{ new Fl_Button(0, 120, 140, 60, "7");
} // Fl_Button* o
{ new Fl_Button(280, 120, 140, 60, "9");
} // Fl_Button* o
o->end();
} // Fl_Double_Window* o
w->show(argc, argv);
return Fl::run();
}
Executando a aplicação 01
Ao ser executada a aplicação ./01
notamos que o redimensionamento está desabilitado, pois
temos na janela principal somente os botões de enrolar, minimizar e fechar
habilitados.

Aplicação 02
A aplicação 02 é uma cópia da 01 com redimensionamento (resizable
) habilitado na janela principal.

Podemos ver pelo diff
abaixo que apenas o flag resizable
foi adicionado e o título da janela foi alterado para 02
.
diff 01.fl 02.fl
8,9c8,9
< label 01 open selected
< xywh {122 262 420 180} type Double visible
---
> label 02 open selected
> xywh {122 262 420 180} type Double resizable visible
Note que agora o botão de maximizar é adicionado:

E podemos redimensionar a janela horizontalmente e verticalmente:


Note que todos os 9 botões são redimensionados da mesma forma.
Aplicação 03
A aplicação 03 é uma cópia da 02 com redimensionamento habilitado no botão 5.

8c8
< label 02 open selected
---
> label 03 open selected
13c13
< xywh {140 60 140 60}
---
> xywh {140 60 140 60} resizable

Ao redimensionar a janela podemos notar alguns comportamentos:
- os botões 1, 3, 7 e 9 (diagonais de 5) permanecem com suas dimensões originais
- os botões 2 e 8 (acima e abaixo de 5) são redimensionados horizontalmente acompanhando o tamanho 5.
- os botões 4 e 6 (à direita e à esquerda de 5) são redimensionados verticalmente acompanhando o tamanho 5.
- comportamento válido quando se tem somente um widget marcado como
resizable
.

Aplicação 04
A aplicação 04 é uma cópia da 02 com redimensionamento habilitado no botão 9.

Observe que o mesmo comportamento geral é aplicado:
- diagonais são mantidas
- acima (e abaixo se houvesse) redimensionados acompanhando a largura de 9
- à esquerda (e à direita se houvesse) redimensionados acompanhando a altura de 9