May 2026
Luciole v2 is a set of libraries and utilities for quickly build GUI’s (Graphical User Interface) for reactive synchronous programs. It targets in particular Lustre programs, but can handle other reactive programs encapsulated into DRO libraries (Dynamic-Loaded Reactive Object).
This section quickly presents the similarities and differences with the previous version of luciole. If you are not familiar with the previous version, you can skip this part.
.dro
files), present since version 1.7,.ec file), which is the
historical supported format..ec or .dro (new) from lustre v4 and lustre v6
(new) programs.Aside these similarities, the core of the tool has been completely remade. In particular, Luciole v2 is almost entirely developed in pure tcltk, while v1 was mostly developed in c++. It makes the portability of the tool much simpler, since it only requires a standard install of tcltk.
simec no longer exists (but the
luciole script provides the same functionality)..iop (input/output panel) format is abandoned. It
was used to customize GUI layouts, and is replaced by a tcltk library
(luc) that provides a similar programming style.Luciole is based on tcltk 8.6, and is made of several components:
ptk,
that provides the bricks for building a reactive GUI and link it to the
reactive programs.luc package. Each .luc file implements a
particular GUI for a particular reactive program. They can be written by
hand, or (transparently) generated by luciole, via an utility
called rp2luc.For a basic usage, the luciole script is sufficient, in
particular it does not require to manipulate a .luc script.
The command-line arguments and the functionalities are the same as
luciole v1.
luciole builds and run a default GUI for running this
particular program: The program inputs/outputs are implemented as
graphical widgets (buttons, sliders, labels etc.), and displayed in a
default 2-columns layout. The default GUI is similar to the one of
luciole v1 (for those who are familiar with).luciole supports two methods for running reactive
program:
execution of native code via a dro file. (compiled
reactive system, packaged into a dynamic library)
interpretation of ec code (Lustre expanded code) via
the ecexe library (embedded in Luciole).
Moreover, luciole provides facilities to deal with other
Lustre formats, in which case external tools are
necessary, as detailed in the sequel.
Executes native code packaged in the dro file.
Interprets the ec code (with embedded ecexe
machine).
Generates a proper ec file, requires external
tools:
lus2ec (default), in
which case a single lustre-v4 file is expected,lv6 compiler, if
-lv6 is specified, in which case one or more lustre-v6
files are expected.Then:
dro file is generated (via
ec2dro), loaded, and executed,For advanced usage, some knowledge on Luciole components is necessary. Some knowledge on tcl programming is indeed also necessary.
Each component is explained in details in the sequel. Here is a list of typical needs, together with the sections to look for:
Adding features to the default gui: see luciolerc.tcl, in default reactive GUI.
Customizing the default in/out layout: some
knowledge on the luc package is necessary, more precisely
the luc panel description section.
Slightly/Completely modify the default GUI: if
possible, you can partly rely the luc library; for really
specific need you will have to program directly at the ptk
level for the graphical part, and the lustubs.so level for
executing reactive programs. In this case, skills in tcl programming is
mandatory.
When called with a reactive program (either lustre or dro), Luciole
generates (via an utility called rp2luc) a luc program with a
simple layout: - a generic menubar, - two columns of widgets (inputs and
outputs), - a global step button.
More precisely, the generated luc scripts ends with the command
stdgui that: - tries to find and load an optional resource
file (see luciolerc) - builds the GUI - enters the tcl loop
Default layout consists in two columns, one for the inputs widgets, one for the outputs.
The user may customize the default GUI by defining a resource file, whose name must be luciolerc.tcl. The extension outlines the fact that this file is a tcl/tk script file. A standard resource file is provided in the Lustre distri- bution which can be copied and modified:
$LUSTRE_INSTALL/lib/luciolerc.tcl
The resource file is automatically searched when luciole has initialized its window. The file is searched first in the current directory, then in the user home directory, and at last in the lustre distribution library:
./luciolerc.tcl
./.luciolerc.tcl
~/luciolerc.tcl
~/.luciolerc.tcl
$LUSTRE_INSTALL/lib/luciolerc.tcl
The first encountered file in the previous list is evaluated as it is by the luciole tcl interpret, and, as a consequence, it has (potentially) access to all internal variable defined by luciole. However it is strongly recommended to only use a few set of variables, as it is explained in the standard resource file.
The default luciolerc.tcl adds a extra Tools that allows the call to the external tool Sim2chro. This tools shows the execution as timing diagrams and comes in two versions: - pure X11 - GTK2
The principle of Luciole v2 is to embbed the reactive program
simulation into a tcl script. As presented before, the
luciole command is a script that builds such a script
(using rp2luc tool) and run it.
The core of Luciole is a tcl package providing commands for: - loading a reactive program, and connect its inputs/outputs to tcl variable, - building the gui using (meta) widgets.
The package contains everal libraries/namespace, the most important being luc.
Here is the content of the Lustre-expanded program
basic.ec:
node basic( x : bool; y : bool; z : int; t : int; u : real;)
returns ( bout1 : bool; bout2 : bool; iout1 : int; iout2 : int; rout : real;);
let
bout1 = x or y ;
bout2 = false -> pre y;
iout1 = (z + t) / 2;
iout2 = 0 -> pre iout2 + 1;
rout = 2.0 * u;
tel
Let’s detail the content of the luc script generated by the command:
rp2luc ecexe basic.ec basic.luc
Setup the environment, and load the library; the
namespace command makes the use of luc:: prefix
optional:
#!/usr/bin/env tclsh
# generated by: rp2luc
lappend auto_path $::env(LUSTRE_INSTALL)/tcl
package require Luciole 2.0
namespace import luc::*
Parse the command line arguments:
# accepts default luciole opts
luc::parse_args
Increase the font (and thus all sizes), since tk defaults are rather small on high-resolution screens:
# change font magnification (%)
ezfont::scale 20
There are two commands to connect and load reactive programs:
Both take as argument: - the name of the tcl command that will be use
to interact with the reactive program (here _panel_)
warning: beware of shadowing existing tcl commands,
e.g. panel is an existing luc command. - the path to the
reactive program (here “basic.ec”, meaning that it must be in the same
folder. - The lists of inputs and outputs, with their identifier and
type.
ecexe _basic_ "basic.ec" {
{ "x" "bool" }
{ "y" "bool" }
{ "z" "int" }
{ "t" "int" }
{ "u" "real" }
} {
{ "bout1" "bool" }
{ "bout2" "bool" }
{ "iout1" "int" }
{ "iout2" "int" }
{ "rout" "real" }
}
For building the GUI, Luciole provides specific widgets, builds over
the ptk library, itself based on the standard
tk library. For the sake of clarity, Luciole specific
widgets are called panel (while widget refer to standard tk
objects).
A “leaf” panel is automatically associated to each input and output,
depending on their type. This default panel is stored in a variable with
the same name~; e.g., $x refers to the default panel
associated to the Boolean input x (button/check button),
while $t refers to a slider.
Basic containers panels allow to organize the GUI in lines and columns:
col { <panel-list> }line { <panel-list> }The panel command allows to name and store a panel:
panel <name> <panel>-text <text> displays the text in the
top of the panelThe main command is `stdgui
panel inputs col -text "Inputs" {
$x $y $z $t $u
}
panel outputs col -text "Outputs" {
$bout1 $bout2 $iout1 $iout2 $rout
}
stdgui line {
$inputs
$outputs
}
Note that using intermediate panels is not mandatory, the following code is completely equivalent:
stdgui line {
col -text "Inputs" { $x $y $z $t $u }
col -text "Outputs" { $bout1 $bout2 $iout1 $iout2 $rout }
}
As mentionned before, Luc(iole) is based on ptk, itself based on tk, there are sereval levels of customization:
Luc containers allow to organize the GUI in lines and columns:
line [-text <string>] { <panel-list> }col [-text <string>] { <panel-list> }Horizontal and vertical bars are similar to lines and columns, except that they only expand in one direction when the wndows s resized:
hbar [-text <string>] { <panel-list> }vbar [-text <string>] { <panel-list> }inbool <ident> [-text <string>] (default
widget for Boolean input)outbool <ident> [-text <string>] (default
widget for Boolean output)outvar <ident> [-text <string>] (default
widget for other types)Default numerical inputs widgets have specific options:
intscale <ident> [opts]realscale <ident> [opts]where (recommanded) options are:
-label <string>-from <num>, -to <num> (min
and max value)-resolution <num> (increment)Luc provides also a “neutral” box leaf, whose goal is just to occupy some space:
box [-text <string>]In addition to the recommanded options presented before, any valid tk option can be passed to the luc panels. These options:
-background yellow), thus a certain knowledge of tk
may help,These are the options that (should) apply to all luc
panels:
-bg, -background-fg, -foreground-activebackground-activeforeground-bd, -borderwidth-cursorSee tcltk documentation to more details on the arguments of these options:
https://www.tcl-lang.org/man/tcl8.6/
Ptk is a library to ease the programming of GUI’s with tcltk. It is used by, but not specific to luciole.
See Ptk manual for details.
They are stored in the examples folder of the
distribution.
Contains the example used in this manual/
This is a simple puzzle game, whose “logic” is programmed in Lustre and graphical interface made with Luciole facilities.
It illustrates several levels of possible customization: