Nux Layouts (part 2)
In Part 1 I introduced Nux’s layouts types and how they structure the widget tree. Now, I will show the anatomy of a the layouts, how they are structured and how their children are placed inside.
Horizontal and vertical layouts
Both of these layouts have separate horizontal and vertical padding and they allow variable space between their children.
In both pictures above (1) represent the layout horizontal padding, (2) the vertical padding and (3) the space between children. The padding allows some space between the children and the layout’s borders. The horizontal and vertical padding may have different values, but the space between items remains the same. All these values can be set through the layout class API.
Grid layouts
Just like horizontal and vertical layouts, grids have paddings and internal space between children. However, the horizontal (4) and vertical (3) space between the children may have different values.
Layered layouts
A layered layout puts layouts on top of each others. At any time, one child of a layered layout is chosen to be the front layout. The front layout is the first child to receive input events in a layered layout. Children of layered layouts may be widgets or layouts of any kind (horizontal, vertical, grid or even layered layouts).
Layered layouts don’t have padding. Instead each child layout defines its own. Layered layout take care of the stacking of the children and their order in the stack.
More about layouts
There are more details about layouts. Although the horizontal and vertical layouts are conceptually simple, they are very flexible in the way they organize the placement of their children. In the next part, I will first define what are the minor and major axis in horizontal and vertical layouts. Then I will show the placement options available to children of these layouts.
Nux Layouts (part 1)
Layouts in Nux are containers of widgets. They group widgets horizontally, vertically, in a grid or stacked one on top of the other. These types of layouts are common in user interfaces. They are simple and easy to understand. Here is a mockup of some layouts:

Horizontal Layout
Layouts may contain widgets and other layouts. Layouts themselves are placed inside widgets. Each widgets may have one and only one layout. Together, widgets and layouts define the widget tree of a Nux user interface.
At the top of the widget tree, there is a layout attached to the client space area of the application window. This is the root layout of the interface.
Layouts are responsible for size management and position of user interface elements. They have a programming interface that allows developers to give instructions that drive size negotiation and position during the layout processing cycle.
The layout system is dynamic. Objects’ size and position inside layouts are automatically computed when certain conditions changes. For instance, if the application window changes size, the root layout will initiate size negotiation through out the widget tree and objects’ size will be re-calculated.
Size negotiation in widgets is complex. It involve going back and forth through the widget tree until the system comes to an equilibrium. However, from a user point of view, the hope is that the layout system is easy to use for simple cases and flexible enough for more advanced configurations.
In the next part, I will be going over details about the layouts internal design.
Nux: Hello World!
Let’s start with the usual suspect: the “Hello World!” program. Using Nux, we are going to create a window and put a button in it. The button reacts (its appearance changes) to mouse events but it isn’t doing anything else. This is what we want to get:

push button
Here is the code to produce it:
#include "Nux/Nux.h"
#include "Nux/VLayout.h"
#include "Nux/WindowThread.h"
#include "Nux/PushButton.h"
void UserInterfaceInitialization(nux::NThread* thread, void* init_data)
{
// Create a vertical Layout
nux::VLayout* layout = new nux::VLayout(NUX_TRACKER_LOCATION);
//Create a button of type PushButton
nux::PushButton* button = new nux::PushButton(
TEXT ("Hello World!"),
NUX_TRACKER_LOCATION);
// Set the button maximum width/height
button->SetMaximumWidth (80);
button->SetMaximumHeight (40);
// Add the button to the layout
layout->AddView (
button,
1,
nux::MINOR_POSITION_CENTER,
nux::MINOR_SIZE_FULL);
// Control the position of elements inside the layout
layout->SetContentDistribution (nux::MAJOR_POSITION_CENTER);
// Set the layout as the container of the window thread
nux::GetWindowThread ()->SetLayout (layout);
// Set the background color of the window
nux::ColorLayer background (nux::Color (0xFF4D4D4D));
static_cast (thread)->SetWindowBackgroundPaintLayer(&background);
}
int main(int argc, char **argv)
{
// Initialize Nux subsystem
nux::NuxInitialize (0);
// Create a Window thread
nux::WindowThread* wt = nux::CreateGUIThread(
TEXT("Push Button"),
200,
150,
0,
&ThreadWidgetInit,
0);
// Start the main loop
wt->Run (0);
delete wt;
return 0;
}
In the first lines of the main function, the program initializes the Nux subsytem:
// Initialize Nux subsystem nux::NuxInitialize (0);
This is followed by the creation of the The WindowThread. A WindowThread is represents a physical window on the desktop. Inside a WindowThread, Nux is listening to window events, passing the events to widgets and doing the rendering.The WindowThread is the first point of entry of the Nux user interface.
The window threads take the following parameters:
- A name to be displayed in the application title bar
- The width and height of the window client area
- A parent window (that we leave to NULL for now)
- A function to be the point of entry of the user interface initialization (user interface initialization function)
- A user defined pointer parameter to pass the user interface initialization function
// Create a Window thread
nux::WindowThread* wt = nux::CreateGUIThread(
TEXT("Push Button"),
200,
150,
0,
&UserInterfaceInitialization,
0);
After that we call Run () on the WindowThread and off we we go! The window is created in a button appears inside. When Run () returns, we destroy the WindowThread and the program exits.
What Run () does is first check if UserInterfaceInitialization is Null or not. If it is not Null, then the function is called to create the user interface of the window. IfUserInterfaceInitialization is Null, then window will be empty, but the main loop will still run. The only thing you can do in this case is close the window.
Now, we take a closer look at the user interface initialization function: UserInterfaceInitialization. In this functions, we create the visual elements that will be displayed inside the window. Nux uses a layout system to host the visual elements inside the WindowThread. Layouts objects are containers. They can negotiate the size and position of visual elements. Nux has a vertical and horizontal layout classes, but more layout can be created. The VLayout and HLayout classes in Nux have have several policies to control the visual elements size and position behavior. We will get to a few of those policies in a moment.
The parameters of UserInterfaceInitialization include the WindowThread that was created in the main () function and the user defined pointer parameter that was passed to CreateGUIThread (last parameter).
The fist object we create is a VLayout. If we have several buttons and we want to display them in the window with a VLayout object, then the buttons will appear stacked vertically one on top of the other.
// Create a vertical Layout nux::VLayout* layout = new nux::VLayout(NUX_TRACKER_LOCATION);
The Button class takes the label on the button as its first parameter. The second parameters to the Button class, NUX_TRACKER_LOCATION (also used in the constructor of VLayout) is optional and yet very useful. It has to do with tracking where objects are allocated. We leave it for another documentation page.
//Create a button of type PushButton
nux::PushButton* button = new nux::PushButton(
TEXT ("Hello World!"),
NUX_TRACKER_LOCATION);
After the button is created, we set it maximum size. This is the time to talk about the basics of size allocation in Nux. Every visual elements as a width and a height parameter. There parameters are bound by a minimum and maximum value set on the visual elements itself. The VLayout/HLayout classes do not changes the min/max width and height of visual elements. Only there actual width and height. VLayout and HLayout will work within the boundaries of every visual elements to try and allocate their size. If their policies allow them to, VLayout and HLayout can grow bigger to make room for all the visual elements or get smaller to tightly pack them.
// Set the button maximum width/height button->SetMaximumWidth (80); button->SetMaximumHeight (40);
Next, the button is added to the layout. This is where we set a few policies to control how the layout manages the button size and position.
layout->AddView (
button,
1,
nux::MINOR_POSITION_CENTER,
nux::MINOR_SIZE_FULL);
The first parameter to AddView is the button itself. The second one is integer number that helps define how much space the button will take from the layout. We will go over this parameter in another documentation page. Let’s spend some time on the last 2 parameters.
A vertical layout as a minor dimension (horizontal direction) and major dimension (vertical direction). The third parameters define where the button will be located in the horizontal direction inside the vertical layout:
- If the button grows to have the same width as the layout, then the third parameter will have no effect. The button will simply use all the horizontal space available.
- If the button’s width is smaller than the layout’s width, then the parameter lets you decide if you want the button to stick to the left, center or right of the layout.
The forth parameter lets you decide if the you want the button to grow horizontally to occupy the full width of the layout (MINOR_SIZE_FULL) or if you want its width to be unchanged (MINOR_SIZE_FIX).
The final steps consist in setting the layout into the WindowThread. During execution, the layout size will be the same as the window size.
// Set the layout as the container of the window thread nux::GetWindowThread ()->SetLayout (layout);
And for the final touch, we give the window a background color.
// Set the background color of the window nux::ColorLayer background (nux::Color (0xFF4D4D4D)); static_cast (thread)->SetWindowBackgroundPaintLayer(&background);
When the function returns, the WindowThread is ready with some visual elements inside. The main loop takes on and the program is realized.
If you look back at the picture at the top, you maybe wondering why the button width does not cover the entire window since we chose the MINOR_SIZE_FULL policy when adding the button to the layout. The reason is that we have forced the maximum size of the button to be 80×40 pixels. Therefore, the button width cannot be bigger than 80 pixels.
Nux and Unity
Canonical is developing its next desktop user interface called Unity. Previously, Unity was based Mutter (Metacity+Clutter). Not long ago, it was decided that Unity will switch from Mutter to Compiz. There are many reasons the for this transition. Chief among them is graphics rendering performance. That doesn’t mean that Mutter or Clutter are not performant. It is just that for what we want to achieve, we need different tools.
For those who don’t know, Compiz is a window manager. Recently, it has been rewritten in C++ (from C). Compiz provides nice desktop effects and transitions. Also, its performance is good for our goal.
Compiz is one aspect of Unity. The other one is Nux. As I said before, Unity was built above the Clutter API. Clutter is a dynamic graphical user interface API with a nice animation framework. In the next version of Unity, Nux is replacing Clutter. Nux is the glue between Compiz and Unity. Nux was originally conceived as a standalone rendering framework but we extended it with what we call an “embeded mode”. The embeded context gives Nux the ability to plug itself into Compiz and allows Unity to be rendered.
Part of my job is to evaluate the graphics features that are required so Unity can run on as many systems as possible. For instance, Unity will support GPUs with OpenGL GLSL but also the old vertex and fragment programs. The list of graphics features required for Unity is still being defined, but we are getting close to having a baseline configuration that, we hope, covers a great number of systems.
Nux
Over the last few years, I have been working on a UI technology for real-time 3D graphics applications. That technology is called Nux and it is now used by Canonical to power the next version of the Ubuntu desktop: Unity. Nux has been made open source, under the LGPL version 3.0 license.
Although, the goal of Nux is still to provide user interface technologies for graphics applications, it is also being re-factored to support the Unity desktop. Myself and a team of software engineers and designers at Canonical, are hard at work to deliver a wonderful desktop experience to Ubuntu users. Nux is one part of Unity that I am happy to contribute to this effort.







