|
Par Lothar Schirm
Traduction française par Jean Debord
Dernière mise à jour : 26 Mars 2015
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 :
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.
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).
Placez la DLL (fltk-c-1.3.3-xx.dll) dans le dossier où vous voulez créer vos programmes, ou bien dans le dossier Windows\System.
Placez les fichiers à inclure (fltk*.bi) dans le dossier inc de FreeBASIC.
Placez la bibliothèque d'importation (libfltk-c-1.3.3-xx.dll.a) dans le dossier lib\win32 de FreeBASIC.
Placez la bibliothèque partagée (libfltk-c-1.3.3-xx.so) dans /usr/lib.
Placez les fichiers à inclure dans le dossier inc de FreeBASIC.
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" |
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 (w as integer, h as integer, title as const zstring ptr = 0) as Fl_Window 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.
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.
La classe Fl_Button inclut les widgets suivants :
Fl_Light_Button : active une « lumière » (un petit carré de couleur apparaît à gauche du bouton quand on clique dessus).
Fl_Check_Button : case à cocher. C'est une sous-classe de Fl_Light_Button.
Fl_Radio_Button : bouton radio
Fl_Repeat_Button : crée des callbacks consécutifs tant qu'il est pressé
Fl_Return_Button : répond à un clic de la souris ou à la touche Return
Fl_Toggle_Button : bascule
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" |
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.
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" |
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 :
Fl_File_Input : permet d'entrer un nom de fichier dans un champ de saisie
Fl_Float_Input : n'autorise que la saisie de nombres en virgule flottante
Fl_Int_Input : n'autorise que la saisie de nombres entiers
Fl_Secret_Input : permet de saisir un mot de passe, les caractères étant remplacés par des marques
Fl_Output : voir ci-dessus
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" |
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 !")
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 :
Fl_File_Browser : affiche une liste de noms de fichiers avec icônes optionnelles
Fl_Hold_Browser : affiche une liste permettant de sélectionner un élément, ce dernier restant marqué en bleu lorsqu'on relâche la souris
Fl_Select_Browser : même chose mais sans marquage
Fl_Multi_Browser : liste avec sélections multiples
Exemple avec Fl_Hold_Browser :
#Include "fltk-c.bi" |
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).
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" |
Et voici le résultat :
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" |
Et voici le résultat :
FL_CHART_BAR : histogramme
FL_CHART_LINE : courbe
FL_CHART_PIE : camembert
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.
Le widget Fl_Choice est une boîte combo. En voici un exemple :
#Include "fltk-c.bi" |
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.
Avec Fl_Menu_Bar nous pouvons créer un menu standard, par exemple :
#Include "fltk-c.bi" |
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 :
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 |
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 r, g, b |
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 s As String |
Dans cet exemple le texte « Henry Miller » peut être modifié.