/**

 \page page_tutorial Tutorials

 \tableofcontents

<!-- ---------------------------------------------------------------------- -->

 \section fluid_hello_world_tutorial Hello, World!

 The first FLUID tutorial explains the FLUID basics. It creates a single
 `main()` function that opens an application window with a static text box
 inside.

 After launching FLUID we want to make sure that two very useful tool windows
 are open.
 The "Widget Bin" gives quick access to all available widgets and functional
 types. It can be opened via the main menu: __Edit > Show Widget Bin__, or
 using the shortcut __Alt-B__.

 The second very helpful tool box is the "Code View". The Code View gives
 a preview of the code as it will be generated by FLUID. All changes in the
 layout or in attributes are reflected immediately in the Code View.
 Choose __Edit > Show Code View__ or press __Alt-C__ to get this
 toolbox. Make sure that _Auto-Refresh_ and _Auto-Position_ are active in
 the Code View.

 Let's start Hello World from scratch. If there is already a previous project
 loaded, select __File > New__ or __Ctrl-N__.

 Before we can create a window, we need a "C" function that can be called
 when we run the program. Select __New > Code > Function/Method...__ or click on
 the
 \image{inline} html flFunction.png "Function/Method"
 \image{inline} latex flFunction.png
 image in the widget bin.

 A function is added as a first line to the widget tree in the main window,
 and a "Function/Method Properties" dialog box will pop up. For our Hello World
 program, delete all text in the top "Name(args)" text field. If this field
 is left empty, FLUID will generate a `main(argc, argv)` function for us.

 \image html fluid4.png "Function/Method Properties Dialog"
 \image latex fluid4.png "Function/Method Properties Dialog" width=7cm

 Click OK to apply the changes you made in the Function Properties dialog.
 You can get this dialog back at any time by selecting the function in the
 main window and pressing __F1__, or by double-clicking it.

 Note that the function will not show up in the Code View yet. FLUID will
 not generate code for functions that don't have any content, and only create
 a forward declaration in the header file, assuming that the function will
 be implemented inside another module.

 Keep the `main` function selected and add an `Fl_Window` to the function by
 selecting __New > Group > Window...__, by clicking the
 \image{inline} html flWindow.png "Group/Window"
 \image{inline} latex flWindow.png
 image in the Widget Bin, or by dragging the Group/Window image from the
 Widget Bin onto the desktop.

 A new application window will open up on the desktop. The thin red outline
 around the window indicates that it is selected. Dragging the red line will
 resize the window. Take a look at the Code View: the main function
 is now generated, including code to instantiate our `Fl_Window`.

 To edit all the attributes of our window, make sure it is selected and press
 __F1__, or double-click the entry in the main FLUID window, or double-click
 the window itself. The "Widget Properties" dialog box will pop up. Enter
 some text in the "Label:" text box and see how the label is updated immediately
 in the window itself, in the widget list, and in the Code View.

 Adding a static text to our window is just as easy. Put an `Fl_Box` into our
 window by selecting __New > Other > Box__, or by clicking on the
 \image{inline} html flBox.png "Other/Box"
 \image{inline} latex flBox.png
 image in the Widget Bin, or by dragging the Other/Box image from the
 Widget Bin into our newly created window.

 Most importantly, enter the text "Hello, World!" in the "Label:" field
 of the Box Widget Properties panel to achieve the goal of this tutorial. Now
 is also a great time to experiment with label styles, label fonts, sizes,
 colors, etc. .

 Finally, we should save our project as an `.fl` project file somewhere. Once
 the project is saved, select __File > Write Code__ or press __Shift-Ctrl-C__
 to write our source code and header file to the same directory.

 Compile the program using a Makefile, CMake file, or fltk-config as described
 in the FLTK manual and the `README.txt` files in the FLTK source tree.

<!-- ---------------------------------------------------------------------- -->

 \section fluid_1of7guis_tutorial 7GUIs, Task 1

 In the first "Hello World" tutorial, we built an entire application in FLUID.
 It's a boring application though that does nothing except quitting when the
 close button in the window border is clicked.

 \image html 1of7GUIs.png "Task 1 of 7GUIs"
 \image latex 1of7GUIs.png "Task 1 of 7GUIs" width=5cm

 The second tutorial will introduce callbacks by implementing task 1, "Counter",
 of 7GUIs. 7GUIs has been created as a spin-off of my master’s thesis
 Comparison of Object-Oriented and Functional Programming for GUI Development
 at the Human-Computer Interaction group of the Leibniz Universität Hannover
 in 2014. 7GUIs defines seven tasks that represent typical challenges in GUI
 programming. https://eugenkiss.github.io/7guis/ .

 Task 1 requires "Understanding the basic ideas of a language/toolkit. The
 task is to build a frame containing a label or read-only textfield T and a
 button B. Initially, the value in T is “0” and each click of B increases the
 value in T by one."

 Our knowledge from tutorial 1 is enough to generate the `main()` function, and
 add an `Fl_Window`, an `Fl_Output`, and an `Fl_Button`. To make life easy,
 FLUID comes with a built-in template for this tutorial. Just select
 __File > New from Template...__ and double-click "1of7GUIs" in the Template
 Panel.

 We will need to reference the output widget in our callback, so let's assign a
 pointer to the widget to a global variable and give that variable a name.
 Open the Widget Properties dialog by double-clicking the output widget.
 Change to the "C++" tab, and enter "`counter_widget`" in the "Name:" field.

 The "Count" button is the active element in our application. To tell the
 app what to do when the user clicks the button, we create a callback function
 for that button. Open the widget properties dialog for the button.
 In the "C++" tab, we find the input field "Callback:".

 The callback is called exactly once every time the user clicks the button. Our
 strategy here is to read the current value from the `counter_widget`,
 increment it by 1, and write it back to `counter_widget`.
 The FLTK documentation tells us that we can use `Fl_Output::ivalue()` to get
 text in `Fl_Output` as an integer, and we can write it back by calling
 `Fl_Output::value(int)`. When the value is changed, FLTK will automatically
 redraw the output widget for us. So here is the callback code:

 ```
 int i = counter_widget->ivalue();
 i++;
 counter_widget->value(i);
 ```

 That's it. This is a complete interactive desktop application. Compile, link,
 run, and test it to see how it works.

<!-- ---------------------------------------------------------------------- -->

\section fluid_cubeview_tutorial Cube View

This tutorial will show you how to generate a complete user interface
class with FLUID that is used for the CubeView program provided with FLTK.

\image html cubeview.png "CubeView demo"
\image latex cubeview.png "CubeView demo" width=7cm

The window is of class CubeViewUI, and is completely generated by FLUID,
including class member functions. The central display of the cube is a
separate subclass of Fl_Gl_Window called CubeView. CubeViewUI manages
CubeView using callbacks from the various sliders and rollers to
manipulate the viewing angle and zoom of CubeView.

At the completion of this tutorial you will (hopefully) understand how to:

-# Use FLUID to create a complete user interface class, including
   constructor and any member functions necessary.
-# Use FLUID to set callback member functions of custom widget classes.
-# Subclass an Fl_Gl_Window to suit your purposes.

\subsection fluid_cubeview The CubeView Class

The CubeView class is a subclass of Fl_Gl_Window. It has methods for
setting the zoom, the \e x and \e y pan, and the rotation angle
about the \e x and \e y axes.

You can safely skip this section as long as you realize that CubeView
is a sublass of Fl_Gl_Window and will respond to calls from
CubeViewUI, generated by FLUID.

\par The CubeView Class Definition

Here is the CubeView class definition, as given by its header file
"test/CubeView.h":
<br>

<!-- Code copied from test/CubeView.h -->
\code
#include <FL/Fl.H>
#include <FL/Fl_Gl_Window.H>
#include <FL/gl.h>

class CubeView : public Fl_Gl_Window {

public:
  CubeView(int x, int y, int w, int h, const char *l = 0);

  // This value determines the scaling factor used to draw the cube.
  double size;

  /* Set the rotation about the vertical (y) axis.
   *
   * This function is called by the horizontal roller in
   * CubeViewUI and the initialize button in CubeViewUI.
   */
  void v_angle(double angle) { vAng = angle; }

  // Return the rotation about the vertical (y) axis.
  double v_angle() const { return vAng; }

  /* Set the rotation about the horizontal (x) axis.
   *
   * This function is called by the vertical roller in
   * CubeViewUI and the initialize button in CubeViewUI.
   */

  void h_angle(double angle) { hAng = angle; }

  // The rotation about the horizontal (x) axis.
  double h_angle() const { return hAng; }

  /* Sets the x shift of the cube view camera.
   *
   * This function is called by the slider in CubeViewUI
   * and the initialize button in CubeViewUI.
   */
  void panx(double x) { xshift = x; }

  /* Sets the y shift of the cube view camera.
   *
   * This function is called by the slider in CubeViewUI
   * and the initialize button in CubeViewUI.
   */
  void pany(double y) { yshift = y; }

  /* The widget class draw() override.
   *
   * The draw() function initializes Gl for another round of
   * drawing, then calls specialized functions for drawing each
   * of the entities displayed in the cube view.
   */
  void draw();

private:
  /*  Draw the cube boundaries.
   *
   * Draw the faces of the cube using the boxv[] vertices,
   * using GL_LINE_LOOP for the faces.
   */
  void drawCube();

  double vAng, hAng;
  double xshift, yshift;

  float boxv0[3]; float boxv1[3];
  float boxv2[3]; float boxv3[3];
  float boxv4[3]; float boxv5[3];
  float boxv6[3]; float boxv7[3];
};
\endcode

\par The CubeView Class Implementation

Here is the CubeView implementation. It is very similar to the
"CubeView" demo included with FLTK.
<br>

<!-- Code copied from test/CubeView.cxx -->
\code
#include "CubeView.h"
#include <math.h>

CubeView::CubeView(int x, int y, int w, int h, const char *l)
  : Fl_Gl_Window(x, y, w, h, l)
{
  Fl::use_high_res_GL(1);
  vAng = 0.0;
  hAng = 0.0;
  size = 10.0;
  xshift = 0.0;
  yshift = 0.0;

  /* The cube definition. These are the vertices of a unit cube
   * centered on the origin.*/

  boxv0[0] = -0.5; boxv0[1] = -0.5; boxv0[2] = -0.5;
  boxv1[0] =  0.5; boxv1[1] = -0.5; boxv1[2] = -0.5;
  boxv2[0] =  0.5; boxv2[1] =  0.5; boxv2[2] = -0.5;
  boxv3[0] = -0.5; boxv3[1] =  0.5; boxv3[2] = -0.5;
  boxv4[0] = -0.5; boxv4[1] = -0.5; boxv4[2] =  0.5;
  boxv5[0] =  0.5; boxv5[1] = -0.5; boxv5[2] =  0.5;
  boxv6[0] =  0.5; boxv6[1] =  0.5; boxv6[2] =  0.5;
  boxv7[0] = -0.5; boxv7[1] =  0.5; boxv7[2] =  0.5;
}

void CubeView::drawCube() {
/* Draw a colored cube */
#define ALPHA 0.5
  glShadeModel(GL_FLAT);

  glBegin(GL_QUADS);
    glColor4f(0.0, 0.0, 1.0, ALPHA);
    glVertex3fv(boxv0);
    glVertex3fv(boxv1);
    glVertex3fv(boxv2);
    glVertex3fv(boxv3);

    glColor4f(1.0, 1.0, 0.0, ALPHA);
    glVertex3fv(boxv0);
    glVertex3fv(boxv4);
    glVertex3fv(boxv5);
    glVertex3fv(boxv1);

    glColor4f(0.0, 1.0, 1.0, ALPHA);
    glVertex3fv(boxv2);
    glVertex3fv(boxv6);
    glVertex3fv(boxv7);
    glVertex3fv(boxv3);

    glColor4f(1.0, 0.0, 0.0, ALPHA);
    glVertex3fv(boxv4);
    glVertex3fv(boxv5);
    glVertex3fv(boxv6);
    glVertex3fv(boxv7);

    glColor4f(1.0, 0.0, 1.0, ALPHA);
    glVertex3fv(boxv0);
    glVertex3fv(boxv3);
    glVertex3fv(boxv7);
    glVertex3fv(boxv4);

    glColor4f(0.0, 1.0, 0.0, ALPHA);
    glVertex3fv(boxv1);
    glVertex3fv(boxv5);
    glVertex3fv(boxv6);
    glVertex3fv(boxv2);
  glEnd();

  glColor3f(1.0, 1.0, 1.0);
  glBegin(GL_LINES);
    glVertex3fv(boxv0);
    glVertex3fv(boxv1);

    glVertex3fv(boxv1);
    glVertex3fv(boxv2);

    glVertex3fv(boxv2);
    glVertex3fv(boxv3);

    glVertex3fv(boxv3);
    glVertex3fv(boxv0);

    glVertex3fv(boxv4);
    glVertex3fv(boxv5);

    glVertex3fv(boxv5);
    glVertex3fv(boxv6);

    glVertex3fv(boxv6);
    glVertex3fv(boxv7);

    glVertex3fv(boxv7);
    glVertex3fv(boxv4);

    glVertex3fv(boxv0);
    glVertex3fv(boxv4);

    glVertex3fv(boxv1);
    glVertex3fv(boxv5);

    glVertex3fv(boxv2);
    glVertex3fv(boxv6);

    glVertex3fv(boxv3);
    glVertex3fv(boxv7);
  glEnd();
} // drawCube

void CubeView::draw() {
  if (!valid()) {
    glLoadIdentity();
    glViewport(0, 0, pixel_w(), pixel_h());
    glOrtho(-10, 10, -10, 10, -20050, 10000);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  }

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glPushMatrix();

  glTranslatef((GLfloat)xshift, (GLfloat)yshift, 0);
  glRotatef((GLfloat)hAng, 0, 1, 0);
  glRotatef((GLfloat)vAng, 1, 0, 0);
  glScalef(float(size), float(size), float(size));

  drawCube();

  glPopMatrix();
}
\endcode

\subsection fluid_cubeview_ui The CubeViewUI Class

We will completely construct a window to display and control the
CubeView defined in the previous section using FLUID.

\par Defining the CubeViewUI Class

Once you have started FLUID, the first step in defining a class is to
create a new class within FLUID using the <b>New->Code->Class</b>
menu item. Name the class "CubeViewUI" and leave the subclass blank.
We do not need any inheritance for this window. You should see the
new class declaration in the FLUID browser window.

\image html  fluid1.png "FLUID file for CubeView"
\image latex fluid1.png "FLUID file for CubeView" width=7cm

\par Adding the Class Constructor

Click on the CubeViewUI class in the FLUID window and add a new method
by selecting <b>New->Code->Function/Method.</b> The name of the
function will also be CubeViewUI. FLUID will understand that this will
be the constructor for the class and will generate the appropriate
code. Make sure you declare the constructor public.

Then add a window to the CubeViewUI class. Highlight the name of
the constructor in the FLUID browser window and click on
<b>New->Group->Window</b>. In a similar manner add the
following to the CubeViewUI constructor:

\li A horizontal roller named \p hrot
\li A vertical roller named \p vrot
\li A horizontal slider named \p xpan
\li A vertical slider named \p ypan
\li A horizontal value slider named \p zoom

None of these additions need be public. And they shouldn't be
unless you plan to expose them as part of the interface for
CubeViewUI.

When you are finished you should have something like this:

\image html fluid2.png "FLUID window containing CubeView demo"
\image latex fluid2.png "FLUID window containing CubeView demo" width=7cm

We will talk about the \p show() method that is highlighted
shortly.

\par Adding the CubeView Widget

What we have is nice, but does little to show our cube. We have already
defined the CubeView class and we would like to show it within the
CubeViewUI.

The CubeView class inherits the Fl_Gl_Window class, which
is created in the same way as an Fl_Box widget. Use
<b>New->Other->Box</b> to add a square box to the main window.
This will be no ordinary box, however.

The Box properties window will appear. The key to letting CubeViewUI
display CubeView is to enter CubeView in the <b>Class:</b> text
entry box. This tells FLUID that it is not an Fl_Box, but a
similar widget with the same constructor.

In the <b>Extra Code:</b> field enter <tt>\#include "CubeView.h"</tt>

This \p \#include is important, as we have just included
CubeView as a member of CubeViewUI, so any public CubeView methods are
now available to CubeViewUI.

\image html fluid3-cxx.png "CubeView methods"
\image latex fluid3-cxx.png "CubeView methods" width=7cm

\par Defining the Callbacks

Each of the widgets we defined before adding CubeView can have
callbacks that call CubeView methods. You can call an external
function or put a short amount of code in the <b>Callback</b>
field of the widget panel. For example, the callback for the
\p ypan slider is:

\code
cube->pany(((Fl_Slider *)o)->value());
cube->redraw();
\endcode

We call <tt>cube->redraw()</tt> after changing the value to update
the CubeView window. CubeView could easily be modified to do this, but
it is nice to keep this exposed. In the case where you may want to do
more than one view change only redrawing once saves a lot of time.

There is no reason to wait until after you have added CubeView to
enter these callbacks. FLUID assumes you are smart enough not to refer
to members or functions that don't exist.

\par Adding a Class Method

You can add class methods within FLUID that have nothing to do with the
GUI. As an example add a show function so that CubeViewUI can actually
appear on the screen.

Make sure the top level CubeViewUI is selected and select
<b>New->Code->Function/Method</b>. Just use the name
\p show(). We don't need a return value here, and since we will
not be adding any widgets to this method FLUID will assign it a return
type of \p void.

\image html fluid4.png "CubeView constructor"
\image latex fluid4.png "CubeView constructor" width=7cm

Once the new method has been added, highlight its name and select
<b>New->Code->Code.</b> Enter the method's code in the code window.

\subsection fluid_addconst Adding Constructor Initialization Code

If you need to add code to initialize a class, for example setting
initial values of the horizontal and vertical angles in the
CubeView, you can simply highlight the constructor and select
<b>New->Code->Code</b>. Add any required code.

\subsection fluid_gencode Generating the Code

Now that we have completely defined the CubeViewUI, we have to generate
the code. There is one last trick to ensure this all works. Open the
preferences dialog from <b>Edit->Preferences</b>.

At the bottom of the preferences dialog box is the key:
<b>"Include Header from Code"</b>.
Select that option and set your desired file
extensions and you are in business. You can include the CubeViewUI.h
(or whatever extension you prefer) as you would any other C++ class.

*/
