<!-- Converted to DocBook/SGML by Kevin Conder -->
<section id="ControlFltkIntro">
  <title>Introduction to FLTK Widgets and GUI controllers</title>

  <para>
    Written by Gabriel Maldonado (<ulink url="http://csounds.com/maldonado"><citetitle>http://csounds.com/maldonado</citetitle></ulink>)
  </para>

  <para>
    Widgets allow the design of a custom Graphical User Interface to control an orchestra in real-time. They are derived from the open-source library FLTK (Fast Light Tool Kit). Such library is one of the fastest graphic libraries available, supports OpenGL and should be source compatible with different platforms (Windows, Linux, Unix and Mac OS). The subset of FLTK implemented in Csound provides the following types of objects:

    <itemizedlist>
      <listitem><para>Containers</para></listitem>
      <listitem><para>Valuators</para></listitem>
      <listitem><para>Other widgets</para></listitem>
    </itemizedlist>
  </para>

  <para>
    Containers are widgets that contain other widgets such as panels, windows, etc. Csound provides the following container objects:

    <itemizedlist>
      <listitem><para>Panels</para></listitem>
      <listitem><para>Scroll areas</para></listitem>
      <listitem><para>Pack</para></listitem>
      <listitem><para>Tabs</para></listitem>
      <listitem><para>Groups</para></listitem>
    </itemizedlist>
  </para>

  <para>
    The most useful objects are named valuators. These objects allow the user to vary synthesis parameter values in real-time. Csound provides the following valuator objects:

    <itemizedlist>
      <listitem><para>Sliders</para></listitem>
      <listitem><para>Knobs</para></listitem>
      <listitem><para>Rollers</para></listitem>
      <listitem><para>Text fields</para></listitem>
      <listitem><para>Joysticks</para></listitem>
      <listitem><para>Counters</para></listitem>
    </itemizedlist>
  </para>

  <para>
    There are other widgets that are not valuators nor containers:

    <itemizedlist>
      <listitem><para>Buttons</para></listitem>
      <listitem><para>Button banks</para></listitem>
      <listitem><para>Labels</para></listitem>
    </itemizedlist>
  </para>

  <para>
    Also there are some other opcodes useful to modify the widget appearance:

    <itemizedlist>
      <listitem><para>Updating widget value.</para></listitem>
      <listitem><para>Setting primary and selection colors of a widget.</para></listitem>
      <listitem><para>Setting font type, size and color of widgets.</para></listitem>
      <listitem><para>Resizing a widget.</para></listitem>
      <listitem><para>Hiding and showing a widget.</para></listitem>
    </itemizedlist>
  </para>

  <para>
    At last, there are three important opcodes that allow the following actions:

    <itemizedlist>
      <listitem><para>Running the widget thread.</para></listitem>
      <listitem><para>Loading snapshots containing the status of all valuators of an orchestra.</para></listitem>
      <listitem><para>Saving snapshots containing the status of all valuators of an orchestra.</para></listitem>
    </itemizedlist>
  </para>

  <para>
    Here is an example preview of Csound code for a window containing a valuator. Notice that all opcodes are init-rate and must be called only once per session. The best way to use them is to place them in the header section of an orchestra, externally to any instrument. Even though placing them inside an instrument is not prohibited, unpredictable results can occur if that instrument is called more than once.
  </para>

  <para>
    Each container is made up of a couple of opcodes: the first indicating the start of the container block and the last indicating the end of that container block. Some container blocks can be nested but they must not be crossed. After defining all containers, a widget thread must be run by using the special FLrun opcode that takes no arguments.
  </para>

  <para>
    Here is an example of creating a window:

    <informalexample>
      <programlisting>
;*******************************
sr=48000
kr=480
ksmps=100
nchnls=1

;*** It is recommended to put almost all GUI code in the
;*** header section of an orchestra

        FLpanel         "Panel1",450,550 ;***** start of container
; some widgets should contained here
        FLpanelEnd     ;***** end of container

        FLrun           ;***** runs the widget thread, it is always required!
instr 1
;put some synthesis code here
endin
;*******************************
      </programlisting>
    </informalexample>

    The previous code simply creates a panel (an empty window because no widgets are defined inside the container).

  </para>

  <para>
    The following example creates two panels and inserts a slider inside each of them:

    <informalexample>
      <programlisting>
;*******************************
sr=48000
kr=480
ksmps=100
nchnls=1

        FLpanel         "Panel1",450,550,100,100 ;***** start of container
gk1,iha FLslider        "FLslider 1", 500, 1000, 2 ,1, ih1, 300,15, 20,50
        FLpanelEnd      ;***** end of container

        FLpanel         "Panel1",450,550,100,100 ;***** start of container
gk2,ihb FLslider        "FLslider 2", 100, 200, 2 ,1, ih2, 300,15, 20,50
        FLpanelEnd      ;***** end of container

        FLrun           ;***** runs the widget thread, it is always required!
instr 1
;put some synthesis code here
; gk1 and gk2 variables that contain the output of valuator
; widgets previously defined, can be used inside any instrument
endin
;*******************************
      </programlisting>
    </informalexample>
  </para>

  <para>
    All widget opcodes are init-rate opcodes, even if valuators output k-rate variables. This happens because an independent thread is run based on a callback mechanism. It consumes very few processing resources since there is no need of polling. (This differs from other MIDI based controller opcodes.) So you can use any number of windows and valuators without degrading the real-time performance.
  </para>

  <para>
    Since FLTK toolkit is still in evolution process, opcode syntax provided in Csound could be modified in future version. This could cause some incompatibilities between orchestras of a determinate version. However it should not be hard to modify early orchestras in order to make them compatible with later versions.
  </para>

  <para>
    For more information, see the following sections.
  </para>

  &controlfltkcontainers;
  &controlfltkvaluators;
  &controlfltkother;

</section>
