Introduction à la programmation graphique avec FLTK

Par Lothar Schirm
Traduction française par Jean Debord

Dernière mise à jour : 26 Mars 2015


  1. Qu'est-ce que FLTK ?
  2. Téléchargement et installation
  3. Un premier programme
  4. Les widgets
    1. Fl_Button
    2. Fl_Input et Fl_Output
    3. Fl_Text_Editor et Fl_Text_Display
    4. Fl_Browser
      1. Liste déroulante
      2. Tableau
    5. Fl_Chart
    6. Fl_Choice
    7. Fl_Menu_Bar, flFileChooser, flMessageBox
    8. Autres dialogues standard

I. Qu'est-ce que FLTK ?

FLTK (Fast Light Toolkit, http://www.fltk.org) est une bibliothèque d'objets graphiques widgets, simple d'emploi, pour Linux et Windows. Initialement prévue pour le langage C (d'où le nom FLTK-C), elle bénéficie actuellement d'une adaptation pour FreeBASIC, ainsi que d'une discussion active sur le forum FreeBASIC dans le sujet suivant :

"FLTK-C wrapper (Fast Light Toolkit v 1.3.3)" par D.J.Peters
http://www.freebasic.net/forum/viewtopic.php?f=14&t=21548

La version actuelle (Mars 2015) est la 1.3.3. Le lien donne l'adresse du téléchargement qui inclut de nombreux exemples permettant de se familiariser avec FLTK.

En plus des objets graphiques (boutons, fenêtres etc.), on peut dessiner directement avec des commandes appropriées ; on peut même utiliser OpenGL. Cependant nous n'aborderons pas ce type de programmation dans cette notice. Nous renvoyons pour cela aux exemples fournis avec le logiciel.

Il existe aussi un générateur d'interfaces nommé FLUID. Cependant, il est conçu pour produire du code C++ et ne peut donc pas s'utiliser avec FreeBASIC.


II. Téléchargement et installation

Commencez par télécharger le logiciel pour FreeBASIC à l'adresse donnée précédemment. La documentation de la version C (http://www.fltk.org/doc-1.3/index.html) peut aussi être utile.

Avec le fichier d'en-tête fltk-c.bi et les exemples inclus dans le logiciel vous avez tout ce qu'il faut pour programmer avec FLTK. Vous pouvez aussi obtenir de l'aide sur le forum FreeBASIC (lien donné dans la section I).

Il existe des versions de FLTK pour les systèmes 32 bits et 64 bits. Dans ce qui suit, la notation xx figurant dans les noms de fichiers correspond à 32 ou 64 selon le système utilisé.

Installation sous Windows

Installation sous Linux


III. Un premier programme

Commençons par un programme simple : une fenêtre intitulée « Bienvenue dans FLTK ! » et un bouton. Quand on clique sur le bouton, le texte « Vous avez cliqué sur le bouton » s'affiche dans la console.

Le code correspondant est très simple :

#Include "fltk-c.bi"

' Fenêtre et widgets
Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Box Ptr Box_text
Dim Shared As Fl_Button Ptr Button_Click


Sub Create_Window_Main ()
' Fenêtre avec bouton

    Window_Main Fl_WindowNew (300200"Test de Bouton")
    Box_text Fl_BoxNew(1008010020"Bienvenue dans FLTK !")
    Button_Click Fl_ButtonNew (10016010020"Cliquez !")

End Sub


Sub Button_Click_Event Cdecl (widget As FL_Widget Ptr)
' Fonction de Callback pour le bouton

  Print "Vous avez cliqué sur le bouton"

End Sub


' Programme principal
Create_Window_Main ()
Fl_WidgetSetCallback0(Button_Click, @Button_Click_Event())
Fl_WindowShow(Window_Main)
Fl_Run

End


Et voici le résultat :




Examinons maintenant le code : que veut dire tout ceci ?

Dans la première ligne nous incluons le fichier d'en-tête fltk-c.bi

Ensuite nous définissons la fenêtre avec ses éléments (boîtes, boutons, champs de saisie etc.). Dans FLTK ces éléments s'appellent des widgets. Toutes les fenêtres et widgets sont passés sous forme de pointeurs, et les chaînes de caractères sont passées sous forme de pointeurs sur des chaînes à zéro terminal (zstring ptr).

Nous préférons écrire la définition de chaque fenêtre dans son propre Sub, bien que cela ne soit pas indispensable, surtout dans de petits programmes comme ceux des exemples. Mais à notre avis cela améliore la clarté du code, particulièrement dans les grands projets qui comportent plusieurs fenêtres. Vous pouvez alors facilement trouver toutes les définitions de vos fenêtres dans l'inspecteur des procédures de votre IDE.

Dans le code nous avons utilisé le widget Fl_Box pour le texte. C'est une simple zone rectangulaire avec un texte.

Nous appelons la fenêtre Window_Main, la boîte Box_text et le bouton Button_Click. Ils sont déclarés par Dim Shared comme variables globales de type FL_Window Ptr, Fl_Box Ptr et Fl_Button Ptr, de sorte que nous pouvons accéder à ces widgets dans les fonctions de callback (voir plus loin).

La définition de notre fenêtre Window_Main prend place dans un Sub appelé Create_Window_Main. Ce Sub nécessite trois fonctions, déclarées dans fltk-c.bi :

Function Fl_WindowNew (as integeras integertitle as const zstring ptr 0as Fl_Window ptr
Function Fl_BoxNew (as integeras integeras integeras integerlabel as const zstring ptr 0as Fl_Box ptr
Function Fl_ButtonNew (as integeras integeras integeras integerlabel as const zstring ptr 0as Fl_Button ptr

Le passage des paramètres, comme dans les fonctions Fl_BoxNew ou Fl_ButtonNew, est toujours le même pour tous les widgets :

D'autres exemples de widgets sont présentés dans les chapitres suivants.

Le Sub Create_Window_Main est suivi par la fonction de callback du Button_Click. Nous l'appelons Button_Click_Event. Il est important d'utiliser Cdecl et un paramètre de type Fl_Widget Ptr. Dans cette fonction nous écrivons ce que doit faire notre programme quand on clique sur le bouton.

Le programme principal est très court. D'abord, on appelle le Sub Create_Window_Main. Ensuite, avec Fl_WidgetSetCallback0 le bouton Button_Click est lié à la fonction de callback. Avec Fl_WindowShow nous affichons la fenêtre sur l'écran (Fl_WindowHide efface une fenêtre, ce qui est particulièrement utile pour les programmes à fenêtres multiples). Avec Fl_Run le programme tourne jusqu'à ce que l'on ferme la fenêtre, soit par son menu contextuel, soit par le bouton de fermeture dans la barre de titre.

Fl_WidgetSetCallback0 semble un peu étrange à cause du 0 à la fin, mais ce n'est pas une faute de frappe ! Il y a plusieurs types de callbacks dans FLTK. Vous pouvez utiliser Fl_WidgetSetCallbackArg, Fl_WidgetSetCallback1Arg ou Fl_WidgetSetCallback pour passer des paramètres à la fonction de callback de différentes manières. Des exemples en sont fournis dans l'archive téléchargée, ainsi que dans ce didacticiel.

Le programme ci-dessus doit bien sûr être compilé sous forme d'application console à cause de l'instruction Print dans la fonction callback. Cela s'applique aussi aux prochains exemples, dans la mesure où ils utilisent cette instruction.

En plus du GUI FLTK nous pouvons aussi utiliser ScreenRes pour ouvrir une fenêtre graphique standard et y dessiner nos propres graphiques avec les instructions de FreeBASIC.

C'est l'avantage des bibliothèques telles que FLTK, GTK+ ou WX-C : nous pouvons encore utiliser la console (de préférence pour les tests et le débogage) ainsi que les fenêtres graphiques standard, tout en ayant le GUI en prime.


IV. Les widgets

FLTK fournit plusieurs classes de widgets.

La classe Fl_Button comporte différent types de boutons, tels que les boutons standard (voir l'exemple précédent, ci-dessus), les bascules, les cases à cocher, les boutons radio...

Les widgets Fl_Input, Fl_Output, Fl_Text_Editor, Fl_Text_Display et Fl_Help_View permettent de saisir et d'afficher des textes, selon des méthodes allant de la plus simple à la plus complexe.

La classe Fl_Valuator inclut, par exemple, les barres de défilement (Fl_Scrollbar) et les glissières (Fl_Slider).

La classe Fl_Menu_ permet la création de menus (Fl_Menu_Bar) et de boîtes combo (Fl_Choice).

La classe Fl_Browser_ permet de représenter les listes et les tables, et d'effectuer des sélections simples ou multiples.

Les widgets peuvent s'organiser selon des onglets (Fl_Tabs), des mosaïques (Fl_Tile), ou des zones que l'on peut faire défiler (Fl_Scroll).

FLTK fournit aussi des boîtes de dialogue standard (common dialogs), telles que les boîtes de message, les boîtes de saisie, les sélecteurs de fichiers ou de couleurs.

Il est impossible de décrire tous les widgets dans cette notice. Les plus importants sont présentés dans la suite, avec quelques exemples. Pour plus de détails, consultez les exemples de l'archive ainsi que la documentation et le fichier fltk-c.bi.


IV.A. Fl_Button

La classe Fl_Button inclut les widgets suivants :

Pour un exemple de bouton simple, voir ci-dessus.

Voici un exemple pour Fl_Toggle_Button, Fl_Radio_Round_Button et Fl_Check_Button (un Fl_Radio_Round_Button a un cercle à gauche avec une marque indiquant l'état « actif » du bouton, tandis que le Fl_Radio_Button agit seulement comme une bascule) :

#Include "fltk-c.bi"

' Widgets
Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Toggle_Button Ptr Button_toggle
Dim Shared As Fl_Group Ptr Group_radio
Dim Shared As Fl_Radio_Round_Button Ptr Button_radio_redButton_radio_yellowButton_radio_green
Dim Shared As Fl_Check_Button Ptr Button_check
Dim Shared As Fl_Button Ptr Button_close


Sub Create_Window_Main ()
' Fenêtre principale avec bouton

    Window_Main Fl_WindowNew (200250"Test des boutons")
    Button_toggle Fl_Toggle_ButtonNew (202010020"Bascule")

    Group_radio Fl_GroupNew (107012090"Choisissez la couleur")
    Fl_GroupBegin (Group_radio)
        Button_radio_red Fl_Radio_Round_ButtonNew (208010020"rouge")
        Button_radio_yellow Fl_Radio_Round_ButtonNew (2011010020"jaune")
        Button_radio_green Fl_Radio_Round_ButtonNew (2014010020"vert")
    Fl_GroupEnd (Group_radio)

    Button_check Fl_Check_ButtonNew (2017010020"OK")
    Button_close Fl_ButtonNew (2020010020"Fermer")

End Sub


Sub Buttons_Event Cdecl (widget As Fl_Widget Ptrarg As Any Ptr)
' Fonctions de Callback pour tous les boutons

    Select Case arg
        Case Button_toggle
            Print Fl_ButtonGetValue (Button_toggle)
        Case Button_radio_red
            Print "rouge"
        Case Button_radio_yellow
            Print "jaune"
        Case Button_radio_green
            Print "vert"
        Case Button_check
            Print Fl_ButtonGetValue (Button_check)
        Case Button_close
            End
    End Select

End Sub


' Programme principal

Create_Window_Main ()

Fl_WidgetSetCallbackArg (Button_toggle, @Buttons_event(), Button_toggle)
Fl_WidgetSetCallbackArg (Button_radio_red, @Buttons_event(), Button_radio_red)
Fl_WidgetSetCallbackArg (Button_radio_yellow, @Buttons_event(), Button_radio_yellow)
Fl_WidgetSetCallbackArg (Button_radio_green, @Buttons_event(), Button_radio_green)
Fl_WidgetSetCallbackArg (Button_check, @Buttons_event(), Button_check)
Fl_WidgetSetCallbackArg (Button_close, @Buttons_event(), Button_close)

Fl_WindowShow (Window_Main)
Fl_Run

End


Et voici le résultat :




Nous avons donc une bascule, trois boutons radio, une case à cocher et un bouton pour fermer la fenêtre et quitter le programme. Nous devons juste grouper les trois boutons radio, afin de n'en cocher qu'un seul à la fois. Cela se fait à l'aide d'un widget Fl_Group et des commandes Fl_GroupBegin et Fl_GroupEnd.

Nous pourrions dès lors écrire une fonction de callback pour chaque bouton, comme à la section III. Mais nous voulons simplifier le code et n'écrire qu'une seule fonction de callback pour les six boutons. Cela se fait en utilisant Fl_WidgetSetCallbackArg au lieu de Fl_WidgetSetCallback0, car alors nous pouvons passer à la fonction un pointeur sur le widget considéré, puis écrire le code correspondant à chaque widget. Le statut d'un bouton (1 ou 0) peut être lu par Fl_ButtonGetValue (voir l'exemple du bouton bascule ou de la case à cocher). L'exemple procède différemment pour les boutons radio, mais même ici nous pourrions utiliser Fl_ButtonGetValue. Bien sûr pour un bouton simple (Fl_Button) cela n'aurait pas beaucoup de sens.


IV.B. Fl_Input et Fl_Output

Le widget Fl_Input est une zone de saisie d'une seule ligne avec une invite, semblable à la commande Input de FreeBASIC. Le widget Fl_Output se présente de la même manière mais se limite à afficher le texte. Il y a aussi des boîtes pour la saisie et l'affichage des textes multilignes (Fl_Multiline_Input et Fl_Multiline_Output).

L'exemple suivant utilise Fl_Input et Fl_Output avec un bouton. Lorsqu'on presse ce dernier le texte saisi dans Fl_Input est copié dans Fl_Output.

#Include "fltk-c.bi"

' Fenêtre et widgets
Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Input Ptr Input_text
Dim Shared As Fl_Output Ptr Output_text
Dim Shared As Fl_Button Ptr Button_Copy


Sub Create_Window_Main ()
' Fenêtre avec widgets

    Window_Main Fl_WindowNew (300200"Test de saisie")
    Input_text Fl_InputNew (1005018020"Texte saisi")
    Output_text Fl_OutputNew (1008018020"Texte copié")
    Button_Copy Fl_ButtonNew (10015010020"Copier")
    Fl_Input_SetValue (Input_text"Editez moi !")

End Sub


Sub Button_Copy_Event Cdecl (widget As FL_Widget Ptr)
' Fonction de Callback pour le bouton

  Dim text As String

  text = *Fl_Input_GetValue (Input_text)
  Fl_Input_SetValue (Output_texttext)

End Sub


' Programme principal
Create_Window_Main ()
Fl_WidgetSetCallback0 (Button_Copy, @Button_Copy_Event())
Fl_WindowShow (Window_Main)
Fl_Run

End


Et voici le résultat :




On peut modifier le texte « Editez moi ! » et le copier dans la zone d'affichage en pressant le bouton « Copier ».

Regardons maintenant le code. C'est une extension de l'exemple donné dans l'introduction. Le sous-programme Button_Click a été renommé en Button_Copy. Dans la déclaration des widgets et dans le Sub Create_Window_Main les nouveaux widgets apparaissent sous les noms Input_text et Output_text. La syntaxe est auto-explicative. Avec Fl_Input_SetValue on initialise le champ de saisie avec un texte modifiable.

Regardons ensuite la fonction de callback. L'instruction text = *Fl_Input_GetValue (input_text) lit le texte du champ de saisie. Notez l'astérisque : la fonction Fl_Input_GetValue retourne un pointeur sur une Zstring. L'astérisque devant la fonction déréférence le pointeur, c'est-à-dire qu'elle retourne le texte pointé (voir le manuel FB). L'instruction Fl_Input_SetValue écrit le texte dans la zone d'affichage, bien qu'il s'agisse d'un widget Fl_Output. Il n'y a pas de commande Fl_Output_SetValue car Fl_Input est placé au-dessus de Fl_Output dans la hiérarchie des widgets.

La classe Fl_Input contient les widgets suivants :


IV.C. Fl_Text_Editor et Fl_Text_Display

Le widget Fl_Text_Editor permet de saisir du texte avec défilement horizontal ou vertical lorsque le texte ne loge pas tout entier dans la boîte.

Exemple de code :

#Include "fltk-c.bi"

' Fenêtre et widgets
Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Text_Editor Ptr Editor_text
Dim Shared As Fl_Text_Buffer Ptr Buffer_text
Dim Shared As Fl_Button Ptr Button_Copy


Sub Create_Window_Main ()
' Fenêtre avec widgets

    Window_Main Fl_WindowNew (300300"Test d'éditeur")
    Editor_text Fl_Text_EditorNew (1010280200)
    Button_Copy Fl_ButtonNew (10023010020"Copier")

    ' Editeur de texte avec texte modifiable
    Buffer_text Fl_Text_BufferNew ()
    Fl_Text_DisplaySetBuffer (Editor_textBuffer_text)
    Fl_Text_BufferSetText (Buffer_text"Prenez la vie du bon côté ! Soyez heureux, ne vous tracassez pas !")

End Sub


Sub Button_Copy_Event Cdecl (widget As FL_Widget Ptr)
' Fonction de Callback pour le bouton

  Dim text As String

  text = *Fl_Text_BufferGetText (Buffer_text)
  Print text

End Sub


' Programme principal
Create_Window_Main ()
Fl_WidgetSetCallback0 (Button_Copy, @Button_Copy_Event)
Fl_WindowShow (Window_Main)
Fl_Run

End

Et voici le résultat :




On peut modifier le texte prédéfini. Lorsqu'on clique sur le bouton « Copier », le texte est copié et affiché dans la console.

Dans ce code il apparaît un nouveau widget : l'éditeur de texte. Malheureusement, il n'est pas possible d'écrire directement dans Fl_Text_Editor, mais seulement par l'intermédiaire d'un tampon Fl_Text_Buffer qui doit être créé puis affecté à l'éditeur au moyen des fonctions Fl_Text_BufferNew et Fl_Text_DisplaySetBuffer (il n'y a pas de Fl_Text_EditorSetBuffer à cause de la hiérarchie des widgets, voir ci-dessus). On peut alors écrire dans le tampon par Fl_Text_BufferSetText ou lire le texte qu'il contient par Fl_Text_BufferGetText (en utilisant l'astérique pour déréférencer le pointeur).

Pour afficher du texte sans en permettre la modification, on utilise le widget Fl_Text_Display que l'on crée par Fl_Text_DisplayNew au lieu de Fl_Text_EditorNew. On peut alors y lire et y écrire du texte à l'aide d'un tampon, comme pour Fl_Text_Editor.

Pour écrire un texte sur plusieurs lignes, on insère un caractère Chr(10) à la fin de chaque ligne :

Fl_Text_BufferSetText (Buffer_text, "L'avenir appartient à ceux" + Chr(10) + "qui se lèvent tôt !")

IV.D. Fl_Browser

Le widget Fl_Browser affiche une liste de chaînes que l'on peut faire défiler. La classe Fl_Browser inclut les widgets suivants :


IV.D.1. Liste déroulante

Exemple avec Fl_Hold_Browser :

#Include "fltk-c.bi"

' Fenêtre et widgets
Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Hold_Browser Ptr Browser_Selection


Sub Create_Window_Main ()
' Fenêtre avec widgets

    Dim As Integer

    Window_Main Fl_WindowNew (200200"Liste déroulante")
    Browser_Selection Fl_Hold_BrowserNew (1010180160"Choisissez un item")
    For To 20
        Fl_BrowserAdd (Browser_Selection"Item " Str (i))
    Next

End Sub


Sub Browser_Selection_Event Cdecl (widget As FL_Widget Ptr)
' Fonction de Callback pour le browser

    Dim As Integer
    Dim text As String

    Fl_BrowserGetValue (Browser_Selection)
    text = *Fl_BrowserGetText (Browser_Selectioni)
    Print i
    Print text

End Sub


' Programme principal
Create_Window_Main ()
Fl_WidgetSetCallback0 (Browser_Selection, @Browser_Selection_Event)
Fl_WindowShow (Window_Main)
Fl_Run

End

Et voici le résultat :




Comme on peut le voir dans le code, les éléments sont ajoutés un par un avec Fl_BrowerAdd. Si l'on veut remplacer les données, on peut effacer le contenu de la liste par Fl_BrowerClear. Par exemple :

Fl_BrowserClear (Browser_Selection)

Le numéro de l'élément sélectionné par la souris est retourné par Fl_BrowserGetValue, et le texte correspondant par Fl_BrowserGetText (voyez la fonction de callback dans le code).


IV.D.2. Tableau

Les widgets Fl_Browser permettent de créer n'importe quel type de liste, ainsi que des tableaux. Dans ce dernier cas, il faut auparavant définir le nombre de colonnes ainsi que leurs largeurs en pixels. Cela se fait à l'aide de la procédure Fl_BrowserSetColumnWidths qui est déclarée de la manière suivante :
Sub Fl_BrowserSetColumnWidths (br Fl_Browser As Ptr, arr As Integer Const Ptr) 

br est un pointeur sur le widget ; arr est un pointeur sur un tableau contenant les largeurs des colonnes, avec en dernier une valeur nulle. Ce tableau doit être de type Integer Const, donc une variable globale.

L'ajout des lignes se fait comme précédemment par Fl_BrowerAdd, les colonnes étant séparées par des tabulations (Chr(9)). On peut aussi définir d'autres délimiteurs au moyen de la procédure Fl_BrowserSetColumnChar qui est déclarée ainsi :

Sub Fl_BrowserSetColumnChar (br Fl_Browser as ptr, c as ubyte) 

Le délimiteur c est défini par le code ASCII du caractère correspondant, p. ex. Asc(";") ou Asc(","). Nous pourrions ainsi afficher les données d'un fichier CSV créé par Excel.

Voici un exemple de code pour créer une table de carrés et de racines carrées :

#Include "fltk-c.bi"

Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Browser Ptr Browser_Table
Dim Shared As Integer col (3) = {8080800}
Dim As Single


Sub CreateWindow_Main
' Fenêtre avec widgets

    Window_Main Fl_WindowNew (300300"Table des carrés et racines")
    Browser_Table Fl_BrowserNew (1010280280)
    Fl_BrowserSetColumnWidths (Browser_Table, @col (0))

End Sub


' Programme principal

CreateWindow_Main ()
Fl_WindowShow (Window_Main)

' Table des fonctions x^2 et Sqr(x)
Fl_BrowserAdd (Browser_Table"x" Chr (9) + "x^2" Chr (9) + "Sqr(x)")
For To 100
    Fl_BrowserAdd (Browser_TableStr(x) + Chr(9) + Str(x^2) + Chr(9) + Str(Sqr(x)))
Next

Fl_Run

End

Et voici le résultat :





IV.E. Fl_Chart

En complément des tableaux, on peut aussi tracer des courbes ou d'autres diagrammes simples avec Fl_Chart.

Exemple avec la fonction sinus :

#Include "fltk-c.bi"

Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Chart Ptr Chart_Sine

Dim As Integer
Dim As Single xdx
Const Pi Atn (1)

Sub CreateWindow_Main ()
' Fenêtre avec diagramme

    Window_Main Fl_WindowNew (400240"Graphe")
    Chart_Sine Fl_ChartNew (1010380200"Temps = 0 à 4*pi")
    Fl_WidgetSetType (Chart_SineFL_CHART_LINE)

End Sub


' Programme principal

CreateWindow_Main ()
Fl_WindowShow (Window_Main)

' Tracer la fonction sinus
dx pi 100
For To 100
    dx
    Fl_ChartAdd (Chart_SineSin(x), ""FL_RED)
Next

Fl_Run

End

Et voici le résultat :




Nous appelons notre widget Chart_Sine (voir le code). Avec Fl_WidgetSetType nous pouvons définir le type de graphique, par exemple :

Avec Fl_ChartAdd les valeurs à représenter sont ajoutées une par une. Le second paramètre est la valeur numérique, le troisième est une étiquette optionnelle, et le dernier est la couleur. Les constantes FL_RED, FL_GREEN, FL_BLUE etc. sont déclarées dans le fichier d'en-tête fltk-c.bi.


IV.F. Fl_Choice

Le widget Fl_Choice est une boîte combo. En voici un exemple :

#Include "fltk-c.bi"

Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Choice Ptr Choice_List


Sub Create_Window_Main ()
' Fenêtre principale

    Dim As Integer

    Window_Main Fl_WindowNew (200240"Boîte combo")
    Choice_List Fl_ChoiceNew (602012020"Choix")
    For To 10
        Fl_Menu_Add (Choice_List"Item " Str(i))
    Next
    Fl_ChoiceSetValue (Choice_List0)

End Sub


Sub Choice_List_Event Cdecl (widget As Fl_Widget Ptr)
' Fonction de Callback

    Print Fl_ChoiceGetValue (Choice_List)

End Sub


' Programme principal

Create_Window_Main ()
Fl_WidgetSetCallback0 (Choice_List, @Choice_List_Event())
Fl_WindowShow (Window_Main)
Fl_Run

End

Et voici le résultat :




Le code ressemble à celui de l'exemple de liste déroulante. Cependant, comme le widget Fl_Choice est une sous-classe de Fl_Menu_, l'ajout de données ne se fait pas avec Fl_ChoiceAdd mais avec Fl_Menu_Add. L'indice du premier élément à afficher est défini par Fl_ChoiceSetValue.


IV.G. Fl_Menu_Bar, flFileChooser, flMessageBox

Avec Fl_Menu_Bar nous pouvons créer un menu standard, par exemple :

#Include "fltk-c.bi"

' Declaration des fonctions de callback - voir plus bas
Declare Sub NewFile Cdecl (widget As Fl_Widget PtruserData As Any Ptr)
Declare Sub OpenFile Cdecl (widget As Fl_Widget PtruserData As Any Ptr)
Declare Sub SaveFile Cdecl (widget As Fl_Widget PtruserData As Any Ptr)
Declare Sub EndProgram Cdecl (widget As Fl_Widget PtruserData As Any Ptr)
Declare Sub Info Cdecl (widget As Fl_Widget PtruserData As Any Ptr)

Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Menu_Bar Ptr Menu


Sub CreateWindow_Main ()
' Fenêtre avec menu

    Window_Main Fl_WindowNew (300200"Test de menu")
    Menu Fl_Menu_BarNew (0030020)
    Fl_Menu_Add (Menu"Fichier/Nouveau" ,,@NewFile())
    Fl_Menu_Add (Menu"Fichier/Ouvrir" ,, @OpenFile())
    Fl_Menu_Add (Menu"Fichier/Enregistrer" ,, @SaveFile())
    Fl_Menu_Add (Menu"Fichier/Quitter" ,, @EndProgram())
    Fl_Menu_Add (Menu"Aide/Info" ,, @Info())

End Sub


' Fonctions de Callback

Sub NewFile Cdecl (widget As Fl_Widget PtruserData As Any Ptr)
    Print "Nouveau fichier"
End Sub

Sub OpenFile Cdecl (widget As Fl_Widget PtruserData As Any Ptr)
    ' Sélectionner le fichier à ouvrir
    Dim As Zstring Ptr file
    file flFileChooser ("Ouvrir fichier""*.bas" Chr(9) + "*.txt"ExePath(), 1)
    If file <> Then Print "Fichier sélectionné : " + *file
End Sub

Sub SaveFile Cdecl (widget As Fl_Widget PtruserData As Any Ptr)
    Print "Enregistrer fichier"
End Sub

Sub EndProgram Cdecl (widget As Fl_Widget PtruserData As Any Ptr)
    End
End Sub

Sub Info Cdecl (widget As Fl_Widget PtruserData As Any Ptr)
    ' Montrer l'info
    flMessageBox ("Information""Programme de test de menu")
End Sub


' Programme principal

CreateWindow_Main ()
Fl_WindowShow (Window_Main)
Fl_Run

End

Et voici le résultat :




Les options du menu sont créées très simplement avec Fl_Menu_Add. Le troisième paramètre (facultatif) spécifie la touche de raccourci pour l'option concernée, p. ex. FL_CTRL + Asc("O") pour « Ouvrir ». Le quatrième paramètre associe l'option du menu avec la fonction de callback correspondante. Cette dernière admet comme second paramètre un pointeur sur une variable userData ; en effet, contrairement aux exemples précédents, Fl_Menu_Add produit un lien sur un Sub de type Fl_Callback au lieu de Fl_Callback0.

Dans les fonctions de callback de cet exemple, nous rencontrons deux dialogues standard : flFileChooser et flMessageBox.

flFileChooser est un dialogue de sélection de fichier. La syntaxe est évidente à l'exception du dernier paramètre, qui vaut 1 pour un chemin relatif et 0 pour un chemin absolu.

flMessageBox est une simple boîte de message comportant un bouton de fermeture.

Voici les captures d'écran correspondantes :

flFileChooser :

flMessageBox :




IV.H. Autres dialogues standard

Pour avoir une boîte de message autorisant plusieurs choix (p. ex. « Oui », « Non », « Annuler ») (jusqu'à 3 boutons), on utilise flChoice.

Exemple :

Dim result As Integer

result flChoice ("Voulez-vous vraiment sortir ?""Oui""Non""Peut-être")

Select Case result
    Case 0
        End
    Case 1
        '.....
    Case 2
        flMessageBox ("Quoi donc ?""Décidez-vous !")
End Select

Autres dialogues standard : flColorChooser et flInput.

flColorChooser permet de choisir une couleur selon différents réglages. Si la couleur doit pouvoir être choisie et exprimée dans le système RGB, la syntaxe est la suivante :

Dim As UBYTE rgb
flColorChooser ("Choisissez une couleur"rgbFL_COLORCHOOSER_BYTE)
Print "Couleur choisie (r, g, b) : "rgb

Les valeurs r, g et b peuvent être prédéfinies dans l'intervalle 0 à 255. FL_COLORCHOOSER_BYTE indique que ces valeurs seront affichées sous forme d'octets (0..255) dans la boîte de dialogue. Avec d'autres indicateurs, il est possible d'exprimer les valeurs (r, g, b) dans l'intervalle 0..1 ou sous forme hexadécimale.

flInput est une boîte de saisie de texte, p. ex. :

Dim As String
= *flInput ("Entrez votre nom :""Henry Miller")
Print s

Dans cet exemple le texte « Henry Miller » peut être modifié.