Documentation Index Fetch the complete documentation index at: https://mintlify.com/fltk/fltk/llms.txt
Use this file to discover all available pages before exploring further.
Fl_Flex is a container widget that arranges children in a single row (horizontal) or column (vertical) with flexible sizing. Introduced in FLTK 1.4.0, it’s the recommended replacement for Fl_Pack with more predictable resize behavior.
Key Features
Automatic horizontal or vertical positioning
Configurable margins around all children
Uniform gap spacing between children
Fixed-size or flexible widgets
Drop-in replacement for Fl_Pack
Creating Fl_Flex
Standard Constructor
Fl_Flex ( int x, int y, int w, int h, const char * label = 0 )
Creates a vertical (column) layout by default:
Fl_Flex * flex = new Fl_Flex ( 10 , 10 , 300 , 200 );
flex -> begin ();
new Fl_Button ( 0 , 0 , 0 , 0 , "Button 1" ); // x,y,w,h ignored
new Fl_Button ( 0 , 0 , 0 , 0 , "Button 2" );
new Fl_Button ( 0 , 0 , 0 , 0 , "Button 3" );
flex -> end ();
Direction Constructors
// Horizontal or vertical layout
Fl_Flex ( int w, int h, int direction)
Fl_Flex ( int x, int y, int w, int h, int direction)
Direction values:
Fl_Flex::HORIZONTAL or Fl_Flex::ROW - Single row
Fl_Flex::VERTICAL or Fl_Flex::COLUMN - Single column (default)
Fl_Flex * toolbar = new Fl_Flex ( 0 , 0 , 800 , 30 , Fl_Flex ::HORIZONTAL);
Layout Direction
Change layout direction with type():
flex -> type ( Fl_Flex ::HORIZONTAL); // Switch to row
flex -> type ( Fl_Flex ::VERTICAL); // Switch to column
// Check direction
if ( flex -> horizontal ()) {
// Row layout
}
Margins and Gaps
Margins (Space Around Children)
// All sides equal
void margin ( int m )
void margin ( int m , int gap ) // Also set gap
// Individual sides
void margin ( int left , int top , int right , int bottom )
// Get margin
int margin () const // Returns left margin
int margin ( int * left , int * top , int * right , int * bottom ) const
Example:
flex -> margin ( 10 ); // 10px on all sides
flex -> margin ( 10 , 5 ); // 10px margin, 5px gap
flex -> margin ( 5 , 10 , 5 , 10 ); // left, top, right, bottom
Gap (Space Between Children)
void gap ( int g )
int gap () const
// Alias for Fl_Pack compatibility
void spacing ( int s )
int spacing () const
Example:
flex -> gap ( 10 ); // 10px between widgets
Fixed vs. Flexible Sizing
Set a widget to have a fixed width (horizontal) or height (vertical):
void fixed ( Fl_Widget * w , int size )
int fixed ( Fl_Widget * w ) const // Get fixed size
Example:
Fl_Flex * toolbar = new Fl_Flex ( 0 , 0 , 600 , 30 , Fl_Flex ::HORIZONTAL);
toolbar -> begin ();
Fl_Button * file = new Fl_Button ( 0 , 0 , 0 , 0 , "File" );
Fl_Button * edit = new Fl_Button ( 0 , 0 , 0 , 0 , "Edit" );
Fl_Box * spacer = new Fl_Box ( 0 , 0 , 0 , 0 ); // Invisible spacer
Fl_Button * exit = new Fl_Button ( 0 , 0 , 0 , 0 , "Exit" );
toolbar -> end ();
// Fixed width buttons
toolbar -> fixed (file, 80 );
toolbar -> fixed (edit, 80 );
toolbar -> fixed (exit, 80 );
// spacer takes all remaining width
Widgets without fixed size share available space equally:
Fl_Flex * row = new Fl_Flex ( 0 , 0 , 600 , 30 , Fl_Flex ::HORIZONTAL);
row -> begin ();
new Fl_Button ( 0 , 0 , 0 , 0 , "Equal" ); // Each gets
new Fl_Button ( 0 , 0 , 0 , 0 , "Width" ); // 1/3 of
new Fl_Button ( 0 , 0 , 0 , 0 , "Buttons" ); // available space
row -> end ();
Horizontal Layout
Widgets arranged in a single row:
Fl_Flex * flex = new Fl_Flex (x, y, w, h, Fl_Flex ::HORIZONTAL);
Behavior:
Width: Fixed widgets use specified width, flexible widgets share remaining space
Height: All widgets stretched to full height (minus margins)
Gap: Horizontal space between widgets
Vertical Layout
Widgets stacked in a single column:
Fl_Flex * flex = new Fl_Flex (x, y, w, h, Fl_Flex ::VERTICAL);
Behavior:
Width: All widgets stretched to full width (minus margins)
Height: Fixed widgets use specified height, flexible widgets share remaining space
Gap: Vertical space between widgets
Complete Example
From examples/howto-flex-simple.cxx:
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Flex.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/fl_ask.H>
void exit_cb ( Fl_Widget * w , void * ) {
fl_message ( "The ' %s ' button closes the window" , w -> label ());
w -> window ()-> hide ();
}
void button_cb ( Fl_Widget * w , void * ) {
fl_message ( "The ' %s ' button does nothing." , w -> label ());
}
int main ( int argc , char ** argv ) {
Fl_Double_Window window ( 410 , 40 , "Simple Fl_Flex Demo" );
// Create horizontal flex container
Fl_Flex flex ( 5 , 5 , window . w () - 10 , window . h () - 10 , Fl_Flex ::HORIZONTAL);
Fl_Button b1 ( 0 , 0 , 0 , 0 , "File" );
Fl_Button b2 ( 0 , 0 , 0 , 0 , "New" );
Fl_Button b3 ( 0 , 0 , 0 , 0 , "Save" );
Fl_Box bx ( 0 , 0 , 0 , 0 ); // Empty space (flexible)
Fl_Button eb ( 0 , 0 , 0 , 0 , "Exit" );
b1 . callback (button_cb);
b2 . callback (button_cb);
b3 . callback (button_cb);
eb . callback (exit_cb);
flex . gap ( 10 ); // 10px between widgets
flex . fixed (bx, 30 ); // Fixed 30px spacer
flex . end ();
window . end ();
window . resizable (flex);
window . size_range ( 300 , 30 ); // Prevent too-small window
window . show (argc, argv);
return Fl :: run ();
}
Common Patterns
Create horizontal flex
Fl_Flex * toolbar = new Fl_Flex ( 0 , 0 , 800 , 35 , Fl_Flex ::HORIZONTAL);
Add left-aligned buttons
toolbar -> begin ();
new Fl_Button ( 0 , 0 , 0 , 0 , "New" );
new Fl_Button ( 0 , 0 , 0 , 0 , "Open" );
new Fl_Button ( 0 , 0 , 0 , 0 , "Save" );
Add flexible spacer
Fl_Box * spacer = new Fl_Box ( 0 , 0 , 0 , 0 ); // Takes all extra space
Add right-aligned button
new Fl_Button ( 0 , 0 , 0 , 0 , "Exit" );
toolbar -> end ();
Fl_Flex * buttons = new Fl_Flex ( 0 , 0 , 400 , 40 , Fl_Flex ::HORIZONTAL);
buttons -> gap ( 5 );
buttons -> margin ( 5 );
buttons -> begin ();
new Fl_Button ( 0 , 0 , 0 , 0 , "OK" ); // Equal
new Fl_Button ( 0 , 0 , 0 , 0 , "Cancel" ); // width
new Fl_Button ( 0 , 0 , 0 , 0 , "Apply" ); // buttons
buttons -> end ();
Fl_Flex * form = new Fl_Flex ( 10 , 10 , 300 , 200 , Fl_Flex ::VERTICAL);
form -> gap ( 10 );
form -> margin ( 10 );
form -> begin ();
Fl_Input * name = new Fl_Input ( 0 , 0 , 0 , 30 , "Name:" );
form -> fixed (name, 30 ); // Fixed height
Fl_Input * email = new Fl_Input ( 0 , 0 , 0 , 30 , "Email:" );
form -> fixed (email, 30 );
Fl_Text_Display * notes = new Fl_Text_Display ( 0 , 0 , 0 , 0 );
notes -> buffer ( new Fl_Text_Buffer ());
// notes is flexible, takes remaining height
Fl_Flex * buttons = new Fl_Flex ( 0 , 0 , 0 , 35 , Fl_Flex ::HORIZONTAL);
buttons -> gap ( 5 );
buttons -> begin ();
new Fl_Box ( 0 , 0 , 0 , 0 ); // Spacer
new Fl_Button ( 0 , 0 , 80 , 0 , "OK" );
new Fl_Button ( 0 , 0 , 80 , 0 , "Cancel" );
buttons -> end ();
form -> fixed (buttons, 35 );
form -> end ();
Nested Flex Layouts
// Main vertical layout
Fl_Flex * main = new Fl_Flex ( 0 , 0 , 600 , 400 , Fl_Flex ::VERTICAL);
main -> begin ();
// Top toolbar (horizontal)
Fl_Flex * toolbar = new Fl_Flex ( 0 , 0 , 0 , 35 , Fl_Flex ::HORIZONTAL);
toolbar -> gap ( 5 );
toolbar -> margin ( 5 );
toolbar -> begin ();
new Fl_Button ( 0 , 0 , 0 , 0 , "File" );
new Fl_Button ( 0 , 0 , 0 , 0 , "Edit" );
new Fl_Box ( 0 , 0 , 0 , 0 ); // Spacer
toolbar -> end ();
main -> fixed (toolbar, 35 );
// Content area (flexible)
Fl_Box * content = new Fl_Box ( 0 , 0 , 0 , 0 , "Content Area" );
content -> box (FL_DOWN_BOX);
// content takes remaining height
// Bottom status bar (horizontal)
Fl_Flex * status = new Fl_Flex ( 0 , 0 , 0 , 25 , Fl_Flex ::HORIZONTAL);
status -> margin ( 5 , 0 , 5 , 0 );
status -> begin ();
new Fl_Box ( 0 , 0 , 0 , 0 , "Ready" );
status -> end ();
main -> fixed (status, 25 );
main -> end ();
Forcing Layout Recalculation
void layout () // Recalculate and redraw
void need_layout ( int set ) // Request recalculation
bool need_layout () const // Check if needed
Call after changing widget sizes or adding/removing children:
flex -> fixed (button, 100 ); // Change size
flex -> layout (); // Apply changes
Best Practices
Set Window Size Range Prevent layout from becoming too small: window -> size_range ( 300 , 200 );
Use Invisible Spacers Create flexible spacing with Fl_Box: Fl_Box * spacer = new Fl_Box ( 0 , 0 , 0 , 0 );
flex -> fixed (spacer, 20 ); // Or leave flexible
Widget Size Ignored Initial widget x, y, w, h are ignored: // All zeros work fine
new Fl_Button ( 0 , 0 , 0 , 0 , "Button" );
Prefer Over Fl_Pack Use Fl_Flex for new code: // BETTER
Fl_Flex * flex = new Fl_Flex (...);
// LEGACY
Fl_Pack * pack = new Fl_Pack (...);
Fl_Pack Compatibility
Fl_Flex can be a drop-in replacement:
Fl_Pack Method Fl_Flex Equivalent spacing(int)gap(int) or spacing(int)type(HORIZONTAL/VERTICAL)type(HORIZONTAL/VERTICAL)horizontal()horizontal()
Key differences:
Fl_Flex doesn’t resize itself (fixed size)
Fl_Flex has margins and more predictable behavior
Fl_Flex supports fixed-size widgets
Reference
Key Methods
Method Description type(int)Set HORIZONTAL or VERTICAL margin(int)Set margin around children gap(int)Set space between children fixed(Fl_Widget*, int)Set fixed size for widget layout()Recalculate layout horizontal()Check if horizontal layout
Enumerations
enum {
VERTICAL = 0 , // Column layout (default)
HORIZONTAL = 1 , // Row layout
COLUMN = 0 , // Alias for VERTICAL
ROW = 1 // Alias for HORIZONTAL
};
See Also