
     _________________________________________________________________

   Widgets and GUI controllers

                            by Gabriel Maldonado
                        http://csounds.com/maldonado
     _________________________________________________________________

   Introduction

   Widgets allow to design a custom Grafic 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:
     * Containers
     * Valuators
     * Other widgets

   Containers are widgets that contain other widgets, such as panels,
   windows etc. Csound provides the following container objects:
     * Panels
     * Scroll areas
     * Pack
     * Tabs
     * Groups

   The most useful objects are named valuators. These objects allow the
   user to vary synthesis parameter values in realtime. Csound provides
   the following valuator objects:
     * Sliders
     * Knobs
     * Rollers
     * Text fields
     * Joysticks
     * Counters

   There are other widgets that are not valuators nor containers:
     * Buttons
     * Button banks
     * Labels

   Also there are some other opcodes useful to modify the widget
   apparence:
     * updating widget value
     * setting primary and selection colors of a widget
     * setting font type, size and color of widgets
     * resizing a widget
     * hiding and showing a widget

   At last, there are three important opcodes that allowing the following
   actions:
     * running  the widget thread
     * saving and loading snapshots containing the status of all
       valuators of an orchestra

   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
   if placing them inside an instrument is not prohibited, unpredictable
   results can occur if that instrument is called more than once). Each
   container are made up of a couple of opcodes, the first indicating the
   start of the container block, 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, widget thread must be
   run, by using the special FLrun opcode, that takes no arguments.For
   example to create a window, the following Csound code is needed:
;********************
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
        FLpanel_end     ;***** end of container

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

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

   The following example creates two panels and inserts a slider inside
   each of them:
;******************************
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
        FLpanel_end     ;***** 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
        FLpanel_end     ;***** 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
;*******************************

   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 which consumes very few processing
   resources, since there is not need of polling (differently from other
   MIDI based controller opcodes). So you can use any number of windows
   and valuators without degrading the realtime performance.

   Since FLTK tookit is still in evolution process, opcode syntax
   provided in Csound could be modified in future version, causing 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.

   For more information see following sections.
     _________________________________________________________________

   Containers

   FLpanel  "label", iwidth, iheight[, ix, iy, iborder]
   FLpanel_end

   FLscroll   iwidth, iheight[, ix, iy]
   FLscroll_end

   FLtabs   iwidth, iheight, ix, iy
   FLtabs_end

   FLgroup  "label", iwidth, iheight, ix, iy [, iborder, image]
   FLgroup_end

   FLpack  iwidth, iheight, ix, iy, itype, ispace, iborder
   FLpack_end

   INITIALIZATION

   label - a double-quoted string  containing the title of the windows or
   a label
   iwidth - width of the widget in pixels
   iheight - heigth of the widget in pixels
   ix - horizontal position of the upper left corner of the widget (in
   pixels)
   iy - vertical position of the upper left corner of the widget (in
   pixels)
   iborder - border type of the container. It is expressed by means of an
   integer number choosen from the following:

          0 - no border
          1 - down box border
          2 - up box border
          3 - engraved border
          4 - embossed border
          5 - black line border
          6 - thin down border
          7 - thin up border

   if the integer number doesn't match any of the previous values, no
   border is provided as default.

   image - a handle referring to an eventual image opened with bmopen
   opcode. If it is set, it allows a skin for that widget

   PERFORMANCE

   There are no k-rate arguments in containers.

   Containers are useful to format the graphic apparence of the widgets.
   The most important container is FLpanel, that actually creates a
   window, that can be filled with other containers and/or valuators or
   other kinds of widgets.

   FLpanel creates a window. It must be followed by the opcode
   FLpanel_end when all widgets internal to it are declared. For example:
        FLpanel         "PanelPluto",450,550,100,100 ;***** start of container
gk1,ih1 FLslider        "FLslider 1", 500, 1000, 2 ,1, -1, 300,15, 20,50
gk2,ih2 FLslider        "FLslider 2", 300, 5000, 2 ,3, -1, 300,15, 20,100
gk3,ih3 FLslider        "FLslider 3", 350, 1000, 2 ,5, -1, 300,15, 20,150
gk4,ih4 FLslider        "FLslider 4", 250, 5000, 1 ,11,-1, 300,30, 20,200
        FLpanel_end     ;***** end of container

   will output the following result:

                                  [Image]

   FLscroll adds scroll bars to an area. Normally you must set arguments
   iwidth, iheight equal to that of the parent window or other parent
   container; ix, iy are optional since normally are set to zero. For
   example the following code:
        FLpanel         "PanelPluto",400,300,100,100
        FLscroll        400,300
gk1,ih1 FLslider        "FLslider 1", 500, 1000, 2 ,1, -1, 300,15, 20,50
gk2,ih2 FLslider        "FLslider 2", 300, 5000, 2 ,3, -1, 300,15, 20,100
gk3,ih3 FLslider        "FLslider 3", 350, 1000, 2 ,5, -1, 300,15, 20,150
gk4,ih4 FLslider        "FLslider 4", 250, 5000, 1 ,11,-1, 300,30, 20,200
        FLscroll_end
        FLpanel_end

   will show scroll bars, when the main window size is reduced:

                                  [Image]

   FLtabs is the "file card tabs" interface that allows useful to display
   several areas containing widgets in the same windows, alternatively.

                                  [Image]

   It must be used together with FLgroup, another container that groups
   child widgets.

   The following example code:
        FLpanel "Panel1",450,550,100,100
        FLscroll        450,550,0,0
        FLtabs  400,550, 5,5
        FLgroup "sliders",380,500, 10,40,1
gk1,ihs FLslider        "FLslider 1", 500, 1000, 2 ,1, -1, 300,15, 20,50
gk2,ihs FLslider        "FLslider 2", 300, 5000, 2 ,3, -1, 300,15, 20,100
gk3,ihs FLslider        "FLslider 3", 350, 1000, 2 ,5, -1, 300,15, 20,150
gk4,ihs FLslider        "FLslider 4", 250, 5000, 1 ,11, -1, 300,30, 20,200
gk5,ihs FLslider        "FLslider 5", 220, 8000, 2 ,1, -1, 300,15, 20,250
gk6,ihs FLslider        "FLslider 6", 1, 5000, 1 ,13, -1, 300,15, 20,300
gk7,ihs FLslider        "FLslider 7", 870, 5000, 1 ,15, -1, 300,30, 20,350
gk8,ihs FLslider        "FLslider 8", 20, 20000, 2 ,6, -1, 30,400, 350,50
        FLgroup_end

        FLgroup "rollers",380,500, 10,30,2
gk1,ihr FLroller        "FLroller 1", 50, 1000,.1,2 ,1 ,-1, 200,22, 20,50
gk2,ihr FLroller        "FLroller 2", 80, 5000,1,2 ,1 ,-1, 200,22, 20,100
gk3,ihr FLroller        "FLroller 3", 50, 1000,.1,2 ,1 ,-1, 200,22, 20,150
gk4,ihr FLroller        "FLroller 4", 80, 5000,1,2 ,1 ,-1, 200,22, 20,200
gk5,ihr FLroller        "FLroller 5", 50, 1000,.1,2 ,1 ,-1, 200,22, 20,250
gk6,ihr FLroller        "FLroller 6", 80, 5000,1,2 ,1 ,-1, 200,22, 20,300
gk7,ihr FLroller        "FLroller 7",50, 5000,1,1 ,2 ,-1, 30,300, 280,50
        FLgroup_end

        FLgroup "joysticks",380,500, 10,40,3
gk1,gk2,ihj1,ihj2 FLjoy "FLjoy", 50, 18000, 50, 18000,2,2,-1,-1,300,300,30,60
        FLgroup_end

        FLtabs_end
        FLscroll_end
        FLpanel_end

   ...will produce the following result:

   [Image] [Image] [Image]

   ...each picture shows a different tab selection of the same windows.

   FLpack provide the functionality of compressing and aligning widgets.
   itype argument expresses the type of packing:

   0 - vertical
   1 - horizontal

   ispace argument sets the space between the widgets contained in
   FLpack.
   iborder sets the border type.

   The following example:
        FLpanel "Panel1",450,300,100,100
        FLpack  400,300, 10,40,0,15,3
gk1,ihs1        FLslider        "FLslider 1", 500, 1000, 2 ,1, -1, 300,15, 20,50
gk2,ihs2        FLslider        "FLslider 2", 300, 5000, 2 ,3, -1, 300,15, 20,100
gk3,ihs3        FLslider        "FLslider 3", 350, 1000, 2 ,5, -1, 300,15, 20,150
gk4,ihs4        FLslider        "FLslider 4", 250, 5000, 1 ,11, -1, 300,30, 20,200
gk5,ihs5        FLslider        "FLslider 5", 220, 8000, 2 ,1, -1, 300,15, 20,250
gk6,ihs6        FLslider        "FLslider 6", 1, 5000, 1 ,13, -1, 300,15, 20,300
gk7,ihs7        FLslider        "FLslider 7", 870, 5000, 1 ,15, -1, 300,30, 20,350
        FLpack_end
        FLpanel_end

   ...will produce this result, when resizing the window:

                                  [Image]
     _________________________________________________________________

  Valuators

   kout, ihandle FLslider  "label", imin, imax, iexp, itype, idisp,
   iwidth, iheight, ix, iy
   kout, ihandle FLknob  "label", imin, imax, iexp, itype, idisp, iwidth,
   ix, iy [,icursorsize]
   kout, ihandle FLroller  "label", imin, imax, istep, iexp, itype,
   idisp, iwidth, iheight, ix, iy
   kout, ihandle FLtext  "label", imin, imax, istep, itype, iwidth,
   iheight, ix, iy
   koutx, kouty, ihandlex, ihandley  FLjoy  "label", iminx, imaxx, iminy,
   imaxy, iexpx, iexpy, idispx, idispy, iwidth, iheight, ix, iy
   kout, ihandle FLcount  "label", imin, imax, istep1, istep2, itype,
   iwidth, iheight, ix, iy, iopcode [, kp1, kp2, kp3, ...., kpN]

   INITIALIZATION

   ihandle -  handle value (an integer number) that univocally references
   to corresponding valuator, used by further opcodes that changes some
   valuator's properties. It is automatically set by the corresponding
   valuator.
   label - a double-quoted string containing  some user-provided text,
   placed near corresponding valuator
   imin, iminx, iminy - minumum value of output range
   imax, imaxx, imaxy -maximum value of output range
   iexp - an integer numeber denoting the behaviuor of valuator: 0 ->
   valuator output is linear; -1 -> valuator output is exponential; all
   other positive numbers indicate the number of an existing table that
   is used for indexing. Linear interpolation is provided in table
   indexing. A negative table number suppresses interpolation. IMPORTANT!
   Notice that tables used by valuators must be created with ftgen
   opcode, placed in the orchestra before corresponding valuator, not
   placed in the score. In fact tables placed in the score are created
   later than the initialization of the opcodes placed in the header
   section of the orchestra.
   itype - an integer number denoting the apparence of the valuator. Its
   meaning is different for different types of valuator (see below for
   details)
   idisp, idispx, idispy - a handle value that was output from a previous
   instance of the FLvalue opcode (see later), to display current value
   of current valuator in FLvalue widget itself. Otherwise (i.e. if the
   user don't want to use this feature that displays current values), it
   must be set to a negative number by the user.
   iwidth - width of valuator
   iheght - height of valuator
   ix and iy - horizontal  and vertical positions of upper left corner of
   the valuator, relative to the upper left corner of corresponding
   window, expressed in pixels
   istep - a floating-point number indicating the increment of valuator
   value corresponding to of each mouse click
   istep1, istep2 - similar to istep, correspond the coarse and fine
   increment, used in FLcount valuator
   iopcode - ascii code indicating the score opcode to be scheduled. At
   present time the only opcode to be scheduled is the score "i"
   statement. So only the ascii value of this opcode (105) is valid. A
   zero value set the defaut of "i" opcode (so at present you can set
   this argument either to 0 or to 105 ,achieving the same result).
   icursorsize - optional. If FLknob itype is set to 1 (3D knob) this
   parameter controls the size of knob cursor.

   PERFORMANCE

   kout - output value
   kp1, kp2, ..., kpN - arguments of the activated instruments (see
   below)

   All valuators ouput their current values in the kout variable, and
   ihandle that is used in some cases by further opcodes (such as
   FLsetVal, see in a later section).

   FLslider opcode puts a slider into the corresponding container. itype
   argument can be set to the following values:

          1 - shows a horizontal fill slider [Image]
          2 - a vertical fill slider
          3 - a horizontal engraved slider [Image]
          4 - a vertical engraved slider
          5 - a horizontal nice slider [Image]
          6 - a vertical nice slider
          7 - a horizontal up-box nice slider
          8 - a vertical up-box nice slider

   imin argument may be greater than imax argument. This has the effect
   of "reversing" the object so the larger values are in the opposite
   direction. This also switches which end of the filled sliders is
   filled.

   FLknob puts a knob in the corresponding container. itype argument can
   be set to the following values:

          1 - a 3-D knob [Image]
          2 - a pie-like knob [Image]
          3 - a clock-like knob [Image]
          4 - a flat knob [Image]

   FLroller is a sort of knob, but put trasversally: [Image] . istep
   argument allow the user to arbitrally slow roller's motion, enabling
   arbitrary precision. 
   itype argument can be set to the following values:

          1 - horizontal roller
          2 - vertical roller

   FLtext allow the user to modify a parameter value by directly typing
   it into a text field: [Image] . Value can also be modified by clicking
   on it and dragging the mouse horizontally. istep argument allow the
   user to arbitrally set the response on mouse dragging.
   itype argument can be set to the following values:

          1 - normal behaviour
          2 - dragging operation is suppressed, instead it will appear
          two arrow buttons. A mouse click on one of these buttons can
          increase/decrease the output value
          3 - text editing is suppressed, only mouse dragging modify
          output value.

   FLjoy is a squared area that allows the user to modify two output
   values at the same time, it acts like a joystick.

   FLcount allows to increase/decrease value with mouse clicks on
   corresponding arrow buttons: [Image] . There are two kind of arrow
   buttons, for larger and smaller steps. Notice that FLcount not only
   outputs a value and a handle, but can also activate (schedule) an
   instrument provided by the user each time a button is pressed.
   P-fields of the activated instrument are kp1 (instrument number), kp2
   (action time), kp3 (duration) and so on with user p-fields. If iopcode
   argument is set to a negative number, no instrument is activated, so
   this feature is optional.
     _________________________________________________________________

   Other Widgets

   kout, ihandle   FLbutton  "label", ion, ioff, itype, iwidth, iheight,
   ix, iy, iopcode [, kp1, kp2, kp3, kp4, kp5, ...., kpN]
   kout, ihandle   FLbutBank   itype, inumx, inumy, iwidth, iheight, ix,
   iy, iopcode [, kp1, kp2, kp3, kp4, kp5, ...., kpN]
   ihandle  Flbox  "label", itype, ifont, isize, iwidth, iheight, ix, iy
   [, image]
   ihandle  FLvalue "label", iwidth, iheight, ix, iy
   FLprintk itime, kval, idisp
   FLprintk2  kval, idisp

   INTIALIZATION

   ihandle - handle value (an integer number) that univocally references
   to corresponding widget, used by further opcodes that modify some
   widget's properties (see next section). It is automatically output by
   the corresponding widget, and must not set by the user
   label - a double-quoted string containing some user-provided text,
   placed near corresponding widget
   ion -  value output when the button is checked
   ioff - value output when the button is unchecked
   itype - an integer number denoting the apparence of the widget. Its
   meaning is different for different types of widget (see below for
   details)
   inumx -  number of buttons in each row of the bank
   inmuy - numebr of buttons in each column of the bank
   iwidth - width of widget
   iheght - height of widget
   ix and iy - horizontal and vertical positions of upper left corner of
   the valuator, relative to the upper left corner of corresponding
   window, expressed in pixels
   ifont - an integer number denoting the font of FLbox
   isize - size of the font
   itime - How much time in seconds is to elapse between updating
   display.
   iopcode - score opcode type. You have to provide the ascii code of the
   letter corresponding to the score opcode. At present time only 'i'
   (ascii code 105) score statements are supported. A zero value refers
   to default opcode that is a "i". So both 0 and 105 activates 'i'
   opcode. a value of -1 disables opcode feature.
   image - a handle referring to an eventual image opened with bmopen
   opcode. If it is set, it allows a skin for that widget

   PERFORMANCE

   kout - output value
   kp1, kp2, ..., kpN - arguments of the activated instruments (see
   below)
   kval - k-rate signal to be displayed

   FLbutton opcode creates a button. Several kind of buttons are
   possible, according to the value of itype argument:

          1 - normal button
          2 - light button
          3 - check button
          4 - round button

   This is the apparence of the buttons:

                                  [Image]

   Buttons of type 2, 3 and 4 also output (kout argument) the value
   contained in ion argument when checked, and that contained in ioff
   arguement, when unchecked.
   By adding 10 to itype argument (i.e. by setting 11 for type 1, 12 for
   type 2, 13 for type 3 and 14 for type 4) it is possible to skip button
   value when getting/setting snapshots (see later section). FLbutton not
   only outputs a value, but can also activate (or schedule) an
   instrument provided by the user each time a button is pressed. If
   iopcode argument is set to a negative number, no instrument is
   activated, so this feature is optional. In order to activate an
   instrument, iopcode must be set to 0 or to 105 (the ascii code of
   character "i", referring to the i score opcode). P-fields of the
   activated instrument are kp1 (instrument number), kp2 (action time),
   kp3 (duration) and so on with user p-fields. Notice that, in dual
   state buttons (light button, check button and round button), the
   instrument is activated only when button state changes from unchecked
   to checked (not when passing from checked to unchecked).

   FLbutBank opcode creates a bank of buttons. For example, the following
   line:
  gkButton,ihb1 FLbutBank       12, 8,8,  380,180, 50,350,  0,7,0,0,5000,6000

   will create the this bank:

                                  [Image]

   A click to a button checks that button, and eventually uncheck a
   previous checked button belonging to the same bank. So the behaviour
   is always that of radio-buttons. Notice that each button is labeled
   with a progressive number.  kout argument is filled with that number
   when corresponding button is checked.
   FLbutBank not only outputs a value, but can also activate (or
   schedule) an instrument provided by the user each time a button is
   pressed. If iopcode argument is set to a negative number, no
   instrument is activated, so this feature is optional. In order to
   activate an instrument, iopcode must be set to 0 or to 105 (the ascii
   code of character "i", referring to the i score opcode). P-fields of
   the activated instrument are kp1 (instrument number), kp2 (action
   time), kp3 (duration) and so on with user p-fields.
   itype argument sets the type of buttons identically to FLbutton opcode
   (see above). By adding 10 to itype argument (i.e. by setting 11 for
   type 1, 12 for type 2, 13 for type 3 and 14 for type 4) it is possible
   to skip current FLbutBank value when getting/setting snapshots (see
   later section).
   FLbutBank is very useful to retreive snapshots.

   FLbox is useful to show some text in a window. The text is bounded by
   a box, whose aspect depends on itype argument. The following values
   are legal for itype:

          1 - flat box
          2 - up box
          3 - down box
          4 - thin up box
          5 - thin down box
          6 - engraved box
          7 - embossed box
          8 - border box
          9 - shadow box
          10 - rounded box
          11 - rounded box with shadow
          12 - rounded flat box
          13 - rounded up box
          14 - rounded down box
          15 - diamond up box
          16 - diamond down box
          17 - oval box
          18 - oval shadow box
          19 - oval flat box

   ifont argument set the font type. The following values are legal for
   ifont:

          1 - helvetica (same as arial under Windows)
          2 - helvetica bold
          3 - helvetica italic
          4 - helvetica bold italic
          5 - courier
          6 - courier bold
          7 - courier italic
          8 - courier bold italic
          9 - times
          10 - times bold
          11 - times italic
          12 - times bold italic
          13 - symbol
          14 - screen
          15 - screen bold
          16 - dingbats

   FLvalue shows current values of a valuator in a text field. It outputs
   ihandle that can then be used as idisp argument of a valuator (see
   previous section). In such a way, the values of that valuator will
   diamically be shown in the text field.

   FLprintk is similar to printk, but shows values of a k-rate signal
   into a text field instead of showing that in the console. idisp
   argument must be filled with the ihandle return value of a previous
   FLvalue opcode. While FLvalue should be placed in the header section
   of an orchestra, inside an FLpanel/FLpanel_end block, FLprintk must be
   placed inside an instrument to operate correctly. For this reason, it
   slows-down performance, and should be used for debugging purposes
   only.

   FLprintk2 is similar to FLprintk, but shows kvar value only each time
   it changes. Useful for monitoring MIDI control changes when using
   sliders. It should be used for debugging purposes only, since it
   slows-down performance.
     _________________________________________________________________

   Modifying Widget Apparence

   FLcolor  ired, igreen, iblue
   FLcolor2  ired, igreen, iblue
   FLlabel  isize, ifont, ialign, ired, igreen, iblue

   FLsetVal_i   ivalue, ihandle
   FLsetVal   ktrig, kvalue, ihandle
   FLsetColor   ired, igreen, iblue,  ihandle
   FLsetColor2  ired, igreen, iblue,  ihandle
   FLsetTextSize  isize, ihandle
   FLsetTextColor    ired, igreen, iblue,  ihandle
   FLsetFont   ifont, ihandle
   FLsetTextType   itype, ihandle
   FLsetText  "itext", ihandle
   FLsetSize  iwidth, iheight, ihandle
   FLsetPosition  ix, iy, ihandle
   FLhide  ihandle
   FLshow  ihandle
   FLsetBox  itype, ihandle
   FLsetAlign  ialign, ihandle
   FLsetImage  imageHandle, ihandle [, iflag]
   FLsetOverlay ktrig, kx, ky, kwidth, kheight, ihandle
   FLtextSize isize

   INITIALIZATION

   ihandle - an integer number (used as unique identifier) taken from the
   output of a previusly located widget opcode (which corresponds to the
   target widget), in order to univocally identify its reference when
   modifying its apparence with this class of opcodes. User must not set
   ihandle value directly, otherwise a Csound crash will occur.
   ired, igreen, iblue - a color of the target widget. It can be the
   first color, second color or font color, according to the opcode. The
   range for each RGB component is 0-255
   ialign - sets the alignment of the label text of widgets
   ifont - sets the the font type of the label of a widget
   ired1, igreen1, iblue1 - first color of the target widget. The range
   for each RGB component is 0-255
   ired2, igreen2, iblue2 - second color (selection color) of the target
   widget. The range for each RGB component is 0-255
   isize - size of the font of the target widget. Normal values are in
   the order of 15. Greater numbers enlarge font size, while smaller
   numbers reduce it.
   iwidth - width of the target widget
   iheght - height of the target widget
   ix and iy - horizontal and vertical positions of upper left corner of
   the target widget, relative to the upper left corner of corresponding
   window, expressed in pixels
   itype - an integer number that modify the apparence of the target
   widget. Its meaning is different for different opcodes (see below for
   details)
   itext - a double-quoted string denoting the text of the label of the
   widget.
   imageHandle - an integer number corresponding to an image opened with
   bmopen. image must be created in array of raw bytes format (iflag
   argument of bmopen set to 1, or 2 if you intend also access array of
   line pointers format)
   iflag - in FLsetImage, resizes the widget according to image size,
   when non-zero.

   PERFORMANCE

   ktrig, kvalue - not implemented yet

   These opcodes modify the apparence of other widgets. There are two
   types of such opcodes, those that don't contain ihandle argument, that
   affect all subsequently declared widgets, and those without ihandle,
   which affect only a target widget previously defined.

   FLcolor sets the primary colors to RGB values given by the user. This
   opcode affects the primary color of (almost) all widgets defined next
   its location. User can put several instances of FLcolor in front of
   each widget he intend to modify. However, to modify a single widget,
   it could be better to use the opcode belonging to the second type
   (i.e. those containing ihandle argument, see below). FLcolor is
   designed to modify the colors of a group of related widget, that
   assume the same colors. The influence of FLcolor on next widgets can
   be turned off by setting -1 as the only argument of the opcode. Also,
   setting -2 (or -3) as the only value of FLcolor makes all next widget
   colors to be randomly selected. The difference is that -2 selects a
   light random color, while -3 selects a dark random color.

   FLcolor2 is the same of FLcolor except it affects the secondary
   (selection) color. Setting it to -1 turns off the influence of
   FLcolor2 on next widgets. A  value of -2 (or -3) makes all next widget
   secondary colors to be randomly selected. The difference is that -2
   selects a light random color, while -3 selects a dark random color.

   FLlabel modifies a set of parameters related to the text label
   apparence of a widget, i.e.  size, font, alignment and color of
   corresponding text. This opcode affects (almost) all widgets defined
   next its location. User can put several instances of FLlabel in front
   of each widget he intend to modify. However, to modify a particular
   widget, it is better to use the opcode belonging to the second type
   (i.e. those containing ihandle argument, see below).  The influence of
   FLlabel on next widgets can be turned off by setting -1 as the only
   argument of the opcode itself. FLlabel is designed to modify text
   attributes of a group of related widget.
   Legal values for ifont argument are:

          1 - helvetica (same as arial under Windows)
          2 - helvetica bold
          3 - helvetica italic
          4 - helvetica bold italic
          5 - courier
          6 - courier bold
          7 - courier italic
          8 - courier bold italic
          9 - times
          10 - times bold
          11 - times italic
          12 - times bold italic
          13 - symbol
          14 - screen
          15 - screen bold
          16 - dingbats

   Legal values for ialign argument are:

          1 - align center
          2 - align top
          3 - align bottom
          4 - align left
          5 - align right
          6 - align top-left
          7 - align top-right
          8 - align bottom-left
          9 - align bottom-right

   FLsetVal_i  forces the value of a valuator to a number provided by the
   user. This can be useful to set the initial values or to reset/update
   widget values for some special task. If the valuator has some graphic
   apparence related to position of its pointer (for example in a
   slider), it affect also pointer position. This and all following
   opcodes belong to the second type of modifiers, since they contain
   ihandle argument. So they affect only a single widget. Notice that,
   when using FLsetVal_i to set the values of FLjoy, two adjacent
   instances of FLsetVal_i are always required, the first matching the X
   value and the second the Y value of FLjoy.

   FLsetVal is almost identical to FLsetVal_i, except it operates at
   k-rate, and it affects target valuator only when ktrig is set to a
   non-zero value. It is not possible to use FLsetVal to set the value of
   FLbutton, FLbutBank and FLjoy. If you attempt to do that, probably a
   Csound crash will occurr.

   FLsetColor sets the primary color of the target widget.

   FLsetColor2 sets the secondary (or selection) color of the target
   widget.

   FLsetTextSize sets the size of the text label of the target widget.

   FLsetTextColor sets the color of the text label of the target widget.

   FLsetFont sets the font type of the target widget. See above for legal
   ifont values.

   FLsetTextType sets some attributes related to the fonts of the text
   label of the target widget.
   In this case, legal values of itype are:

          0 - normal label
          1 - no label (hides the text)
          2 - symbol label (see below)
          3 - shadow label
          4 - engraved label
          5- embossed label
          6- bitmap label (not implemented yet)
          7- pixmap label (not implemented yet)
          8- image label (not implemented yet)
          9- multi label (not implemented yet)
          10- free-type label (not implemented yet)

   When using itype=3 (symbol label), it is possible to assign a
   graphical symbol instead of the text label of the target widget. In
   this case, the string of the target label must always start with '@';
   if it starts with something else (or the symbol is not found) the
   label is drawn normally. The following symbols are supported:

                               [symbols.gif]

   The @ sign may be followed by the following optional "formatting"
   characters, in this order:
     * '#' forces square scaling, rather than distortion to the widget's
       shape.
     * +[1-9] or -[1-9] tweaks the scaling a little bigger or smaller.
     * [1-9] - rotates by a multiple of 45 degrees. '6' does nothing, the
       others point in the direction of that key on a numeric keypad.

   Notice that, with FLbox and FLbutton, it is not necessary to call
   FLsetTextType opcode at all in order to use a symbol. In this case is
   sufficient set a label starting with '@' followed by the proper
   formatting string.

   FLsetText sets the label of the target widget to the double-quoted
   text string provided with itext argument.

   FLsetSize resize the target widget (not the size of the text),
   according to iwidth and iheight arguments.

   FLsetPosition sets the position of the target widget according to ix
   and iy arguments. Their values corrspond to the upper left corner of
   the widget and are relative to the upper left corner of the window
   that contain the widget.

   FLhide hides target widget, making it invisible.

   FLshow restore the visibility of a previously hidden widget.

   FLsetBox set the apparence of a box surrounding the target widget.
   Legal values for itype argument are:

          1 - flat box
          2 - up box
          3 - down box
          4 - thin up box
          5 - thin down box
          6 - engraved box
          7 - embossed box
          8 - border box
          9 - shadow box
          10 - rounded box
          11 - rounded box with shadow
          12 - rounded flat box
          13 - rounded up box
          14 - rounded down box
          15 - diamond up box
          16 - diamond down box
          17 - oval box
          18 - oval shadow box
          19 - oval flat box

   FLsetAlign sets the text alignment of the label of the target widget.
   See above for legal ialign values.

   FLsetImage shows a RGB image inside or near the corresponding widget.
   imageHandle argument is an integer number corresponding to an image
   already opened with bmopen opcode. iflag argument (optional) can
   assume the following integer values:

          0 - places the image into the center of parent widget
          1 - resizes the parent widget according to image size
          2 - tiles the image inside parent widget

   FLsetOverlay draws a rectangle over a widget, that can be modified at
   performance time. This can be useful, for example to draw a moving
   cursor following an image playing with bmscan opcode.

   FLtextSize sets the size of all subsequent text fonts.
     _________________________________________________________________

   General Widget-related Opcodes

   FLrun

   inumSnap, inumVal   FLsetsnap   index [, ifn]
   inumSnap FLgetsnap index

   FLsavesnap "filename"
   FLloadsnap "filename"

   INITIALIZATION

   inumSnap - current number of snapshots
   inumVal - number of valuators (whose value is stored in a snapshot)
   present in current orchestra
   ifn - optional argument referring to an already allocated table, to
   store values of a snapshot.
   index - a number referring univocally to a snapshot. Several snapshots
   can be stored in the same bank.
   filename - a double-quoted string corresponding to a file to store or
   load a bank of snapshots

   FLrun opcode must be located at the end of all widget declarations. It
   has no arguments, and its purpose is to start the thread related to
   widgets. Widgets would not operate if FLrun is missing.

   FLsetsnap opcode stores current status of all valuators present in the
   orchestra into a snapshot location (in memory). Any number of
   snapshots can be stored in current bank. Banks  are structures that
   only exist in memory, there are no other reference to them other that
   they can be accessed by FLsetsnap, FLsavesnap, FLloadsnap
   and FLgetsnap opcodes. Only a single bank can be present in memory. If
   ifn argument (optional) refers to an already allocated and valid
   table, the snapshot will be stored in the table, instead of in the
   bank. So that table can be accessed from other Csound opcodes. index
   argument univocally refers to a determinate snapshot. If the value of
   index refers to a previously stored snapshot, all its old values will
   be replaced with current ones. If index refers to a snapshot that
   doesn't exist, a new snapshot will be created. If index value is not
   adjacent with that of a previously created snapshot, some empty
   snapshots will be created (for example, if location with index 0
   contains the only and unique snapshot present in a bank, and the user
   stores a new snapshot using index 5, all locations between 1 and 4
   will automatically contain empty snapshots). Empty snapshots don't
   contain any data and are neutral. FLsetsnap outputs current number of
   snapshots (inumSnap argument) and the total number of values stored in
   each snapshot (inumVal), that is equal to the number of valuators
   present in the orchestra.

   FLgetsnap retreives a previously stored snapshot (in memory), i.e.
   sets all valuator to the corresponding values stored in that snaphot.
   index argument univocally must refer to an already existent snapshot.
   If index argument refers to an empty snapshot or to a snapshot that
   doesn't exist, no action is done. FLsetsnap outputs current number of
   snapshots (inumSnap argument).

   FLsavesnap saves all snapshots currently created (i.e. the entire
   memory bank) into a file whose name is filename. Since the file is a
   text file, snapshot values can also be edited manually, by means of a
   text editor. The format of data stored in the file is the following
   (at present time, this could be changed in next Csound version):
----------- 0 -----------
FLvalue 0 0 1 0 ""
FLvalue 0 0 1 0 ""
FLvalue 0 0 1 0 ""
FLslider 331.946 80 5000 -1 "frequency of the first oscillator"
FLslider 385.923 80 5000 -1 "frequency of the second ocillator"
FLslider 80 80 5000 -1 "frequency of the third ocillator"
FLcount 0 0 10 0 "this index must point to the location number where snaphsot is stored"
FLbutton 0 0 1 0 "Store snapshot to current index"
FLbutton 0 0 1 0 "Save snapshot bank to disk"
FLbutton 0 0 1 0 "Load snapshot bank from disk"
FLbox 0 0 1 0 ""
----------- 1 -----------
FLvalue 0 0 1 0 ""
FLvalue 0 0 1 0 ""
FLvalue 0 0 1 0 ""
FLslider 819.72 80 5000 -1 "frequency of the first oscillator"
FLslider 385.923 80 5000 -1 "frequency of the second ocillator"
FLslider 80 80 5000 -1 "frequency of the third ocillator"
FLcount 1 0 10 0 "this index must point to the location number where snaphsot is stored"
FLbutton 0 0 1 0 "Store snapshot to current index"
FLbutton 0 0 1 0 "Save snapshot bank to disk"
FLbutton 0 0 1 0 "Load snapshot bank from disk"
FLbox 0 0 1 0 ""
----------- 2 -----------
..... etc...
----------- 3 -----------
..... etc...
---------------------------

   As you can see, each shapshot contain several lines. Each snapshot is
   separated from previous and next snapshot by a line of this kind:
   "----------- snapshot Num -----------". Then there are several line
   containing data. Each of these lines corresponds to a widget. The
   first field of each line is an unquoted string containing opcode name
   corresponding to that widget. Second field is a number that expresses
   current value of a snapshot. In current version this is the only field
   that can be modified manually. The third and fourth fields shows
   minimum and maximum values allowed for that valuator. Fifth field is a
   special number that indicates if the valuator is linear (value 0),
   exponential (value -1), or is indexed by a table interpolating values
   (negative table numbers) or non-interpolating (positive table
   numbers). Last field is a quoted string with the label of the widget.
   Last line of the file is always "---------------------------".
   Note that FLvalue and FLbox are not valuators, and their values are
   fixed, cannot be modified.

   FLloadsnap loads all snapshots contained in filename into the memory
   bank of current orchestra.
     _________________________________________________________________

   Slider Bank

   FLslidBnk   "names", inumsliders [, ioutable, iwidth, iheight, ix, iy,
   itypetable, iexptable, istart_index, iminmaxtable]

   INITIALIZATION

   names -  a double-quoted string containing the names of each slider.
   Each slider can have a different name. Separate each name with '@'
   character, for example "frequency@amplitude@cutoff". It is possible to
   not provide any name by giving a single space " "; in this case the
   opcode will automatically assign a progressive number as a label for
   each slider.
   inumsliders - number of sliders
   ioutable - number of a previously-allocated table in which to store
   output values of each slider. User must be sure that table size is
   large enough to contain all output cells, otherwise a segfault will
   crash Csound. By assigning zero to this argument, the output will be
   directed to the zak space, in the k-rate zone. In this case hte zak
   space must be previously allocated with the zakinit opcode, and the
   user must be sure that the allocation size is big enough to cover all
   sliders. Default is zero (i.e. store output in zak space).
   istart_index - an integer number referring to a starting offset of
   output cell locations. It can be positive to allow multiple banks of
   sliders to output in the same table or in the zak space. Default is
   zero (no offset).
   iminmaxtable - number of a previously-defined table containing a list
   of min-max pairs, referred to each slider. A zero value defaults 0 to
   1 range for all slider, without necessity to provide a table. Default
   is zero
   iexptable -  number of a previously-defined table containing a list of
   identifiers (i.e. integer numbers) provided to modify the behaviour of
   each slider independently. Identifiers can assume the following
   values:

          -1 = exponential curve response
          0 = linear response
          number > than 0 = follow the curve of a previously-defined
          table to shape response of corresponding slider. In this case
          the number corresponds to table number.

   you can assume that all sliders of the bank have the same response
   curve (exponential or linear), in this case you can assign -1 or 0 to
   iexptable, without worring to previously define any table.Default
   value is zero (all sliders have a linear response, without having to
   provide a table).
   itypetable - number of a previously-defined table containing a list of
   identifiers (i.e. integer numbers) provided to modify the aspect of
   each individual slider independently. Identifiers can assume the
   following values:

          1 = Fill slider
          3 = Normal slider
          5 or 0 = Nice slider
          7 = Nice slider with down-box

   you can assume that all sliders of the bank have the same aspect, in
   this case you can assign a negative number to itypetable without
   worring to previously define any table. Negative numbers have the same
   meaning of the corresponding positive identifiers, with the difference
   that the same aspect is assigned to all sliders. You can also assign a
   random aspect to each slider, by setting itypetable to a negative
   number lower than -7. Default value is zero (all sliders have the
   aspect of nice sliders, without having to provide a table).
   iwidth, iheight - width and height of the rectangular area containing
   all sliders of the bank , excluding text labels, that are placed at
   the left of that area.
   ix, iy - horizontal and vertical position of the upper left corner of
   the rectangular area containing all sliders belonging to the bank. You
   have to leave enough space, at the left of that rectangle, in order to
   make labels of sliders to be visible, since labels themselves are
   external to the rectangular area.

   PERFORMANCE

   there are no k-rate arguments, even if cells of the output table (or
   the zak space) are updated at k- rate.

   FLslidBnk is a widget containing a bank of horizontal sliders. Any
   number of sliders can be placed into the bank (inumsliders argument).
   The output of all sliders is stored into a previously allocated table
   or into the zak space (ioutable argument). It is possible to determine
   the first location of the table (or of the zak space) in which to
   store the output of the first slider by means of istart_index
   argument. Each slider can have an individual label, that is placed at
   the left of it. Labels are defined by the "names" argument (see above,
   in the parameter description section). The output range of each slider
   can be individually set, by means of an external table (iminmaxtable
   argument). Curve response of each slider can be set individually, by
   means of a list of identifiers placed in a table (iexptable argument).
   It is possible to define the aspect of each slider indendently or to
   make all sliders have the same aspect (itypetable argument). iwidth,
   iheight, ix and iy, determine width, height, horizontal and vertical
   position of the rectangular area containing sliders. Notice that the
   label of each slider is placed at the left of them, and is not
   included in the rectagular area containing sliders, so the user should
   leave enough space at the left of the bank, by assigning a proper ix
   value in order to leave labels visible.
