1# NanoGUI 2 3[![Documentation Status](https://readthedocs.org/projects/nanogui/badge/?version=latest)](http://nanogui.readthedocs.org/en/latest/?badge=latest) 4[![Build Status](https://travis-ci.org/wjakob/nanogui.svg?branch=master)](https://travis-ci.org/wjakob/nanogui) 5[![Build status](https://ci.appveyor.com/api/projects/status/m8h3uyvdb4ej2i02/branch/master?svg=true)](https://ci.appveyor.com/project/wjakob/nanogui/branch/master) 6 7NanoGUI is a minimalistic cross-platform widget library for OpenGL 3.x or higher. 8It supports automatic layout generation, stateful C++11 lambdas callbacks, 9a variety of useful widget types and Retina-capable rendering on Apple devices 10thanks to [NanoVG](https://github.com/memononen/NanoVG) by Mikko Mononen. 11Python bindings of all functionality are provided using 12[pybind11](https://github.com/wjakob/pybind11). 13 14## Example screenshot 15![Screenshot](https://github.com/wjakob/nanogui/raw/master/resources/screenshot.png "Screenshot") 16 17## Description 18NanoGUI builds on [GLFW](http://www.glfw.org/) for cross-platform OpenGL context 19creation and event handling, [GLAD](https://github.com/Dav1dde/glad) to use OpenGL 203.x Windows, [Eigen](http://eigen.tuxfamily.org/index.php?title=Main_Page) for 21basic vector types, and [NanoVG](https://github.com/memononen/NanoVG) to draw 222D primitives. 23 24Note that the dependency library NanoVG already includes some basic example 25code to draw good-looking static widgets; what NanoGUI does is to flesh it 26out into a complete GUI toolkit with event handling, layout generation, etc. 27 28NanoGUI currently works on Mac OS X (Clang) Linux (GCC or Clang) and Windows 29(Visual Studio ≥ 2015); it requires a recent C++11 capable compiler. All 30dependencies are jointly built using a CMake-based build system. 31 32## Creating widgets 33NanoGUI makes it easy to instantiate widgets, set layout constraints, and 34register event callbacks using high-level C++11 code. For instance, the 35following two lines from the included example application add a new button to 36an existing window `window` and register an event callback. 37```C++ 38Button *b = new Button(window, "Plain button"); 39b->setCallback([] { cout << "pushed!" << endl; }); 40``` 41 42The following lines from the example application create the coupled 43slider and text box on the bottom of the second window (see the screenshot). 44```C++ 45/* Create an empty panel with a horizontal layout */ 46Widget *panel = new Widget(window); 47panel->setLayout(new BoxLayout(BoxLayout::Horizontal, BoxLayout::Middle, 0, 20)); 48 49/* Add a slider and set defaults */ 50Slider *slider = new Slider(panel); 51slider->setValue(0.5f); 52slider->setFixedWidth(80); 53 54/* Add a textbox and set defaults */ 55TextBox *textBox = new TextBox(panel); 56textBox->setFixedSize(Vector2i(60, 25)); 57textBox->setValue("50"); 58textBox->setUnits("%"); 59 60/* Propagate slider changes to the text box */ 61slider->setCallback([textBox](float value) { 62 textBox->setValue(std::to_string((int) (value * 100))); 63}); 64``` 65 66The Python version of this same piece of code looks like this: 67```Python 68# Create an empty panel with a horizontal layout 69panel = Widget(window) 70panel.setLayout(BoxLayout(BoxLayout.Horizontal, BoxLayout.Middle, 0, 20)) 71 72# Add a slider and set defaults 73slider = Slider(panel) 74slider.setValue(0.5f) 75slider.setFixedWidth(80) 76 77# Add a textbox and set defaults 78textBox = TextBox(panel) 79textBox.setFixedSize(Vector2i(60, 25)) 80textBox.setValue("50") 81textBox.setUnits("%") 82 83# Propagate slider changes to the text box 84def cb(value): 85 textBox.setValue("%i" % int(value * 100)) 86slider.setCallback(cb) 87``` 88 89## "Simple mode" 90 91Christian Schüller contributed a convenience class that makes it possible to 92create AntTweakBar-style variable manipulators using just a few lines of code. 93For instance, the source code below was used to create the following example 94application. 95 96![Screenshot](https://github.com/wjakob/nanogui/raw/master/resources/screenshot2.png "Screenshot") 97 98 99```C++ 100/// dvar, bar, strvar, etc. are double/bool/string/.. variables 101 102FormHelper *gui = new FormHelper(screen); 103ref<Window> window = gui->addWindow(Eigen::Vector2i(10, 10), "Form helper example"); 104gui->addGroup("Basic types"); 105gui->addVariable("bool", bvar); 106gui->addVariable("string", strvar); 107 108gui->addGroup("Validating fields"); 109gui->addVariable("int", ivar); 110gui->addVariable("float", fvar); 111gui->addVariable("double", dvar); 112 113gui->addGroup("Complex types"); 114gui->addVariable("Enumeration", enumval, enabled) 115 ->setItems({"Item 1", "Item 2", "Item 3"}); 116gui->addVariable("Color", colval); 117 118gui->addGroup("Other widgets"); 119gui->addButton("A button", [](){ std::cout << "Button pressed." << std::endl; }); 120 121screen->setVisible(true); 122screen->performLayout(); 123window->center(); 124``` 125 126## Compiling 127Clone the repository and all dependencies (with `git clone --recursive`), 128run CMake to generate Makefiles or CMake/Visual Studio project files, and 129the rest should just work automatically. 130 131On Debian/Ubuntu, make sure that you have installed the following packages 132```bash 133$ apt-get install cmake xorg-dev libglu1-mesa-dev 134``` 135To also get the Python bindings, you'll need to run 136```bash 137$ apt-get install python-dev 138``` 139### License 140 141nanogui is provided under a BSD-style license that can be found in the 142``LICENSE.txt`` file. By using, distributing, or contributing to this project, 143you agree to the terms and conditions of this license. 144