Boost.UI
User Interface Boost library
Boost.UI Documentation

Table of Contents

Introduction

Boost.UI is a C++ User Interface (GUI) Boost library that

It supports Graphics, various Widgets, Events, Layouts.

Motivation

C++ programs should have a better way to interact with humans then std::cin / std::cout.

Examples and screenshots

"Hello, World!" application

hello_windows7.png
"Hello, World!" application under Windows 7
// Copyright (c) 2017 Kolya Kosenko
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
// "Hello, World" example
// This example creates dialog with one button. When user press button
// informational dialog is shown.
// Include all Boost.UI headers
#include <boost/ui.hpp>
namespace ui = boost::ui;
int ui_main()
{
// Create dialog window with title
ui::dialog dlg("Hello, Boost.UI!");
// Put button with title on this dialog window
ui::button(dlg, "Say &hello")
// Subscribe to button press events to callback function
.on_press([]
{
// Handle button press event
// Show informational dialog window with text
// and wait while user close it
ui::info_dialog("Hello, C++ World!");
});
// Show dialog window
// and wait while user close it
dlg.show_modal();
return 0;
}
int main(int argc, char* argv[])
{
// Initialize GUI, call ui_main function, uninitialize GUI, catch exceptions
return ui::entry(&ui_main, argc, argv);
}

Bootstrap application

bootstrap_unity.png
Bootstrap application under Unity
// Copyright (c) 2017 Kolya Kosenko
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
// Text processor
// This example creates dialog with input and output fields, and one button
// between them. When user press button, reversed input field text copied into output field.
// Input field is cleared.
#include <boost/ui.hpp>
#include <sstream>
namespace ui = boost::ui;
class bootstrap_dialog : public ui::dialog
{
typedef bootstrap_dialog this_type;
public:
bootstrap_dialog();
private:
void process();
ui::text_box m_input_widget;
ui::label m_output_widget;
};
bootstrap_dialog::bootstrap_dialog()
: ui::dialog("Bootstrap example")
{
// Create vertical box layout inside dialog window
// and put children widgets inside it
ui::vbox(*this)
<< ui::label(*this, "Input:")
<< m_input_widget.create(*this, "Boost.UI default input data 0123456789")
.tooltip("Input string")
.layout().justify().stretch()
<< ui::button(*this, "&Process")
.on_press(&this_type::process, this)
.tooltip("Process input data")
<< ui::label(*this, "Output:")
<< m_output_widget.create(*this)
.tooltip("Output")
.layout().justify().stretch()
;
// Change dialog window size
resize(400, 300);
}
void bootstrap_dialog::process()
{
// Read string from input widget
std::wstring data = m_input_widget.text().wstring();
// TODO: Add your process code here
std::reverse(data.begin(), data.end());
std::wostringstream ss;
ss << data;
// Write string to output widget
m_output_widget.text(ss.str());
// Clear input widget text
m_input_widget.clear();
}
int ui_main()
{
bootstrap_dialog().show_modal();
return 0;
}
int main(int argc, char* argv[])
{
return ui::entry(&ui_main, argc, argv);
}

Screenshots

demo_unity.png
Demo application under Unity
demo_windows7.png
Demo application under Windows 7
demo_windows_xp.png
Demo application under Windows XP
demo_windows95.png
Demo application with Windows 95 theme

Overview

Initialization

Boost.UI library master include file is <boost/ui.hpp>

#include <boost/ui.hpp>

and this library uses boost::ui namespace to hold all classes and functions.

namespace ui = boost::ui;

Boost.UI requires GUI initialization and uninitialization, therefore you should use boost::ui::entry() function to do it.

int ui_main()
{
run_gui();
return 0;
}
int main(int argc, char* argv[])
{
return ui::entry(&ui_main, argc, argv);
}

Widgets

Widget is a graphical control element and represents any visible object on screen. boost::ui::widget is a base class for all widgets. Widget should be created to be visible and use its functions, boost::ui::widget::native_valid() function returns true in this case.

See also
Widget (Wikipedia)

Top level widgets (TLW)

Top level widgets (TLW) are widgets that are used to host other (child) widgets and they are controlled by OS window manager. Basic TLW is boost::ui::dialog. If you need boost::ui::menu_bar or boost::ui::status_bar support you should use boost::ui::frame TLW. boost::ui::window is a base class for all (two) TLW classes. boost::ui::window::show_modal() class function displays TLW and waits while end user close TLW manually or boost::ui::window::close() class function is called.

class my_dialog : public ui::dialog
{
public:
my_dialog() : ui::dialog("Dialog example")
{
ui::button(*this, "&Close this dialog")
.on_press(&my_dialog::on_close, this);
}
private:
void on_close()
{
close();
}
};
void run_dialog()
{
my_dialog().show_modal();
}

boost::ui::frame with boost::ui::menu_bar and boost::ui::status_bar support:

class my_frame : public ui::frame
{
typedef my_frame this_type;
public:
my_frame() : ui::frame("Frame example")
{
ui::button(*this, "&Close this frame")
.on_press(&this_type::on_close, this);
menu_bar()
<< ( ui::menu("&File")
<< ui::menu::item("&Quit")
.on_press(&this_type::on_close, this)
)
;
status_bar().text("Ready");
}
private:
void on_close()
{
close();
}
};
void run_frame()
{
my_frame().show_modal();
}
See also
Window (Wikipedia)

Child widgets

Child widget is a widget that is placed on parent widget (top level widget (TLW) or other child widget - boost::ui::panel). Parent widget should be specified for each child widget as a first argument in constructor. Child widget is automatically destroyed when parent widget is destroyed.

2D drawing on canvas

If you want to draw lines, circles, etc you should use boost::ui::canvas child widget and draw using drawing context - boost::ui::painter class. Other widgets not support drawing.

See also
Canvas (Wikipedia)

Thread safety

Boost.UI is NOT thread safe library, so you should use boost::ui::call_async() function to synchronize worker threads with main (GUI) thread. However you can use Logging in any thread, it is thread safe.

Event loops

Boost.UI has own event loops and you can't create other your own event loops inside main (GUI) thread without freezing GUI. For example if you are using Boost.ASIO you should create other (worker) thread and synchronize it with main thread as described before. Note that main thread is used to interact with end user, not for long time calculations.

Event handing

Widgets have various event subscription functions (for example boost::ui::button::on_press()). If you pass callback function to it, this function will be called when event occurs (button press in this case). Multiple subscription calls cause multiple event handlers calls, i. e. event handler callback function isn't overrided on next event subscription call.

See also
Event (Wikipedia)

Exception safety

Boost.UI catches exception inside boost::ui::entry() and event handlers if you didn't catch it before. After exception catch library shows exception dialog window to the end user.

Strings

Boost.UI has own boost::ui::uistring string class that simplifies conversion between native widget toolkit string classes and C++ Standard string classes. Native string format could be ANSI, UTF-8, wchar_t etc.

WinMain() under Windows

WinMain() function is used under Windows as entry point for GUI applications, but Boost.UI requires main() function. You can call main() from WinMain() by including into your cpp file:

#include <boost/ui/native/winmain.cpp>

Or make this call manually.

Source code

See source code (GitHub). Read README.md file for build instructions and library details.

See also
User interface (Wikipedia)
Graphical user interface (Wikipedia)
Text-based user interface (Wikipedia)
Widget toolkit (Wikipedia)
Look and feel (Wikipedia)
Human interface guidelines (Wikipedia)