PHP GTK vol2  

Dans notre dernier tutoriel [lien] nous avons découvert PHP-GTK.

Mais cela n'était qu'une introduction assez peu parlante. Nous allons maintenant développer notre première application disposant d’un réel intérêt ! Comme vous le savez votre serviteur, moi même, vous a déjà proposé des articles sur Ming (extension PHP permettant de générer du flash) [lien1][lien2]. Nous allons donc faire d'une pierre deux coups et créer un petit utilitaire pour Ming :

Lors de la génération d’animation flash avec Ming, on peut utiliser des fonts spécifiques au format FDB. Il existe deux utilitaires en ligne de commande permettant de générer ces fichiers à partir de font TTF :
  • Tt2fft : transforme une font TTF en font FFT (format de fichier utilisé dans les templates flash)
  • MakeFDB : transforme une font FFT en font FDB.

Le but principal de ce tutorial sera un « frontend » pour ces deux utilitaires. PHP-GTK étant multi plateforme, nous allons faire en sorte que notre outil le soit aussi. Ainsi nous agirons différement selon que nous serons sous Windows ou Linux.

Pour plus d’information, allez à l’adresse suivante : http://blue.ribbon.to/~harpy/ming/jaming/index_en.html (en anglais)
Image


Le code source

Pour permettre un développement plus efficace, j’ai adopté une programmation orientée objet. Dans un premier temps, nous allons décrire les différentes classes, la création de l’interface graphique, les différentes fonctions du cœur de l’application puis la jonction entre les éléments réactifs et ces fonctions. Vous pouvez télécharger le code source ici : FDBBuilder

 

Les élements réactifs

note : Avant de commencer veuillez noter que nous basons notre code sur PHP4.

La classe "champ texte"

Cette classe permet la saisie d’un texte sur une seule ligne.

  • La méthode « GetText() permet d’obtenir le texte spécifié par l’utilisateur.
  • La méthode « SetText() permet de mettre à jour le texte de ce composant.
  • La méthode « GetHandle() sera utilisé pour insérer l’instance de l’objet dans l’interface graphique.

La classe champ texte
  1. <?php
  2. class TextInput
  3. {
  4.   function TextInput()
  5.   {
  6.      $this->Obj = &new GtkEntry();
  7.   }
  8.  
  9.   function GetText()
  10.   {
  11.     return $this->Obj->get_text();
  12.   }
  13.   function SetText($NewText)
  14.   {
  15.     $this->Obj->set_text($NewText);
  16.   }
  17.  
  18.   function GetHandle()
  19.   {
  20.     return $this->Obj;
  21.   }
  22. }
  23. ?>

 

La classe bouton

Lorsque l’on créé un bouton, on définit trois choses :
  • On spécifie son nom,
  • on spécifie son action lorsque l’on clique dessus,
  • on spécifie l’aide contextuelle qui apparaît lorsque l’utilisateur laisse sa souris plusieurs secondes dessus.

Grâce à <?php $this->Obj->connect('clicked', $Action);?> on associe l’état cliqué à l’action spécifiée. Dans les quatre dernières ligne de la méthode Button, on créé notre aide contextuelle en spécifiant un délais de 200 ms avant son apparition.

 

La classe bouton
  1. <?php
  2. class Button
  3. {
  4.   function Button($Name, $Action, $ToolTipString)
  5.   {
  6.     $this->Obj = &new GtkButton($Name);
  7.     /* On spécifie la fonction qui sera appelée lorsque l'on clique sur le bouton */
  8.     $this->Obj->connect('clicked', $Action);
  9.  
  10.     // Si on laisse la souris sur le bouton plus de 200 ms,
  11.     // une aide apparaîtra pour informer sur l'action du bouton
  12.     $this->ToolTips[$Name] = &new GtkTooltips();
  13.     $this->ToolTips[$Name]->set_delay(200);
  14.     $this->ToolTips[$Name]->set_tip($this->Obj, $ToolTipString, '');
  15.     $this->ToolTips[$Name]->enable();
  16.   }
  17.  
  18.   function GetHandle()
  19.   {
  20.     return $this->Obj;
  21.   }
  22. }
  23. ?>

 

La classe zone texte

Notre champ texte permet la saisie d’un texte sur plusieurs lignes. Dans la méthode SetText(), on est obligé en premier lieu d’effacer ce que contient notre objet puis d’insérer notre texte. Sans cette procédure, notre méthode reviendrait à faire appel à AddText();.

La classe zone texte
  1. <?php
  2. class TextArea
  3. {
  4.   function TextArea()
  5.   {
  6.      $this->Obj = &new GtkText();
  7.   }
  8.  
  9.   function GetText()
  10.   {
  11.     return $this->Obj->get_text();
  12.   }
  13.   function SetText($NewText)
  14.   {
  15.     // Si on ne detruit pas le texte courant,
  16.     // le nouveau texte sera concaténé à l'ancien
  17.     $this->Obj->delete_text(0, -1);
  18.     $this->Obj->insert(null, null, null, $NewText);
  19.   }
  20.   function AddText($NewText)
  21.   {
  22.     $this->Obj->insert(null, null, null, $NewText);
  23.   }
  24.   function SetEditable($Status)
  25.   {
  26.     $this->Obj->set_editable($Status);
  27.   }
  28.   function GetHandle()
  29.   {
  30.     return $this->Obj;
  31.   }
  32. }
  33. ?>

 

Le coeur de l'application

Gestion de la selection de la font

Lorsque la police a été sélectionnée, on utilise ttf2fft pour afficher les informations contenues dans cette police. Dans cette méthode, on récupère le chemin et le nom de la font. On concatène ces deux informations pour permettre à GetFontInformation de nous retourner les informations attendues. Pour terminer, on insère ces informations dans le champ texte prévu à cet effet.
Gestion de la selection de la font
  1. <?php
  2. function FileSelectionOkAction()
  3. {
  4.   global $FileSelection;
  5.   global $MyTextInput;
  6.   global $ConvertionResult;
  7.  
  8.   $FileSelection->hide();
  9.   $SelectionText    = $FileSelection->selection_text;
  10.   $FFT_FontPath     = str_replace("Selection: ", "", $SelectionText->get());
  11.   $FileDirectory    = $FFT_FontPath;
  12.   $SelectionEntry   = $FileSelection->selection_entry;
  13.   $FileName         = $SelectionEntry->get_text();
  14.   $FilePath         = $FileDirectory . "/" . $FileName;
  15.   $MyTextInput->SetText($FilePath);
  16.   GetFontInformation($FilePath);
  17.   $ConvertionResult->SetText("Convertion Result");
  18. }
  19. ?>

 

Les informations sur la font

Cette fonction est appelée par la fonction FileSelectionOkAction().
On utilise l’outil ttf2fft avec l’option –l. Pour éxécuter la ligne de commande on se sert de la fonction PHP exec(). Celle-ci stock les retours sous forme d'un tableau de chaîne de caractère. Par la suite, on concatène chaque chaîne de caractère séparée par un retour ligne pour intégrer un minimum de mise en page. Une fois fait, on insère notre nouvelle chaîne de caractère dans notre zone de texte prévu à cet effet.

 

Les informations sur la font
  1. <?php
  2. function GetFontInformation($FilePath)
  3. {
  4.   global $FontInfo;
  5.  
  6.   $CommandLine = 'ttf2fft.exe "' . $FilePath . '/" -l';
  7.   exec($CommandLine,$tab);
  8.   foreach ($tab as $elem)
  9.   {
  10.     $Message .= $elem."\n";
  11.   }
  12.   $FontInfo->SetText($Message);
  13. }
  14. ?>

 

La convertion de la font

Cette fonction exécute la conversion de la font sélectionnée.
Dans un premier temps, on vérifie que tous les paramètres requis ont été spécifiés par l’utilisateur. Ensuite, on utilise TTF2FFT et MakeFdb pour convertir la font. Pour chaque étape on insère les informations retournées par les outils dans le champ texte prévu à cet effet pour informer l’utilisateur de l’avancement de la conversion. Une fois terminée, on efface le fichier .fft qui a été généré durant la conversion mais qui ne nous est d’aucune utilité.
La convertion de la font
  1. <?php
  2. function Convert()
  3. {
  4.   global $MyTextInput;
  5.   global $CharmapNumberInput;
  6.   global $FaceNumberInput;
  7.   global $ConvertionResult;
  8.  
  9.   $TTF_FontPath = $MyTextInput->GetText();
  10.   $CharMapNumber = $CharmapNumberInput->GetText();
  11.   $FaceNumber = $FaceNumberInput->GetText();
  12.  
  13.   if (!strlen($TTF_FontPath))
  14.     msg_box("Oh no ....", 2, "No font selected", "Ok", 2);
  15.   else if (!strlen($CharMapNumber))
  16.     msg_box("Oh no.....", 2, "You must select a charmap number", "OK", 2);
  17.   else if  (!strlen($FaceNumber))
  18.     msg_box("Oh no.....", 2, "You must select a face number", "OK", 2);
  19.   else
  20.   {
  21.     $FFT_FontPath = str_replace("ttf", "fft", $TTF_FontPath);
  22.     $FFT_FontPath = str_replace("TTF", "FFT", $TTF_FontPath);
  23.     if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
  24.         $CommandLine = "ttf2fft.exe "" . $TTF_FontPath . "/" -o "" . $FFT_FontPath."/"";
  25.     else
  26.         $CommandLine = "ttf2fft /"" . $TTF_FontPath . "/" -o /"" . $FFT_FontPath."/"";
  27.     if ($CharMapNumber != "")
  28.       $CommandLine .= " -e " . $CharMapNumber;
  29.     if ($FaceNumber != "")
  30.       $CommandLine .= " -f " . $FaceNumber;
  31.     $Result = "##########################\n ####### TTF to FFT #######\n##########################\n";
  32.     $ExecReturn = exec($CommandLine, $TabResult);
  33.     foreach ($TabResult as $elem)
  34.     {
  35.       $Result .= $elem."\n";
  36.     }
  37.     $ConvertionResult->SetText($Result);
  38.     if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
  39.         $CommandLine = "MakeFdb.exe /"" . $FFT_FontPath . "/"";
  40.     else
  41.         $CommandLine = "MakeFdb /"" . $FFT_FontPath . "/"";
  42.     $Result = "\n\n##########################\n ####### FFT to FDB #######\n##########################\n";
  43.     exec($CommandLine, $TabResult);
  44.     foreach ($TabResult as $elem)
  45.     {
  46.       $Result .= $elem."\n";
  47.     }
  48.     $ConvertionResult->AddText($Result);
  49.     $CommandLine = "del /"" . $FFT_FontPath . "/"";
  50.     exec($CommandLine, $TabResult);
  51. }
  52. }
  53. ?>

 

Mise en place de l'interface utilisateur.

Après avoir créé chaque élément réactif, il faut les inclure dans la fenêtre principale. Comme nous l'avons vu dans le premier tutorial, l'inclusion de chaque élément a son importance dans la disposition finale.
Note : Pour faciliter cette étape, je vous recommande d'utiliser des box.

Les différentes box

Mise en place de l'interface utilisateur.
  1. <?php
  2.   $GeneralButtonsBox    = & new GtkHBox();
  3.   $GeneralButtonsBox->set_spacing(5);
  4.   $GeneralButtonsBox->set_border_width(10);
  5.  
  6.   $BrowseBox            = & new GtkHBox();
  7.   $BrowseBox->set_spacing(5);
  8.   $BrowseBox->set_border_width(10);
  9.  
  10.   $OptionsBox           = & new GtkHBox();
  11.   $OptionsBox->set_spacing(5);
  12.   $OptionsBox->set_border_width(10);
  13.  
  14.   $TextAreasBox         = & new GtkVBox();
  15.   $TextAreasBox->set_spacing(5);
  16.   $TextAreasBox->set_border_width(10);
  17.  
  18.  
  19.   $VerticalBox          = & new GtkVBox();
  20.   $VerticalBox->set_spacing(5);
  21.   $VerticalBox->set_border_width(0);
  22. ?>

 

Les éléments réactifs et informatifs.



Pour rendre l'interface graphique un peu plus jolie on va intègré une pixmap "PHPTEAM". Pour cela on utilise la classe GtkPixmap qui requiert une pixmap et un mask BMP que l'on obtient depuis un fichier xpm grâce à la méthode pixmap_create_from_xpm().

Les éléments réactifs et informatifs.
  1. <?php
  2.   $MyBrowseButton   = new Button("Browse", 'Browse', "Select a font to convert");
  3.   $MyConvertButton  = new Button("Convert", 'Convert', "Convert the font");
  4.   $MyExitButton     = new Button("Exit", 'Quit', "Exit The Application");
  5.   $FaceNumberLabel  = & new GTKLabel("Face Number: ");
  6.   $FaceNumberInput  = new TextInput();
  7.   $CharmapNumberLabel = &new GTKLabel("Charmap number: ");
  8.   $CharmapNumberInput = new TextInput();
  9.   $FontInfo         = new TextArea();
  10.   $FontInfo->SetEditable(false);
  11.   $FontInfo->SetText("Font Information");
  12.   $ConvertionResult = new TextArea();
  13.   $ConvertionResult->SetEditable(false);
  14.   $ConvertionResult->SetText("Convertion Result");
  15.  
  16.   list($pixmap, $mask) = Gdk::pixmap_create_from_xpm($window->window,null,'phpteam.xpm');
  17.   $PhpTeamImage     = & new GtkPixmap($pixmap, $mask);
  18. ?>

 

Disposition des éléments

C'est la partie déterminante pour disposer nos éléments dans l'interface utilisateur.
Un bouton dans une box qui elle même se retrouve à l'intérieur d'une box.
Note : Amusez vous à changer l'ordre d'ajout des différentes box dans la VerticalBox pour mieux comprendre le principe.

Disposition des éléments
  1. <?php
  2. $BrowseBox->add($MyBrowseButton->GetHandle());
  3. $GeneralButtonsBox->add($MyConvertButton->GetHandle());
  4. $GeneralButtonsBox->add($MyExitButton->GetHandle());
  5. $OptionsBox->add($FaceNumberLabel);
  6. $OptionsBox->add($FaceNumberInput->GetHandle());
  7. $OptionsBox->add($CharmapNumberLabel);
  8. $OptionsBox->add($CharmapNumberInput->GetHandle());
  9. $TextAreasBox->add($FontInfo->GetHandle());
  10. $TextAreasBox->add($ConvertionResult->GetHandle());
  11.  
  12. $VerticalBox->add($PhpTeamImage);
  13. $VerticalBox->add($BrowseBox);
  14. $VerticalBox->add($OptionsBox);
  15. $VerticalBox->add($TextAreasBox);
  16. $VerticalBox->add($GeneralButtonsBox);
  17. $window->add($VerticalBox);
  18. ?>

 

Conclusion.

Et voila notre première application de réalisée. Vous êtes maintenant fin prêt à développer tout type d'application. Cependant développer une application de cette façon implique beaucoup de travail. Heuresement il existe une possibilité de le faire simplement via Glade.
Glade est une librairie pour GTK qui permet de définir l'interface graphique en XML et comporte même un RAD. Donc la prochaine étape sera la réécriture de notre application avec Glade.

Les liens.

Feed RSS du site sur PHP-gtk :http://gtk.php.net/news.rss

Les utilitaires pour la création des fonts sous windows : http://blue.ribbon.to/~harpy/ming/jaming/win/jaming-win.zip

Les utilitaires pour la création des fonts sous Linux : http://blue.ribbon.to/~harpy/ming/jaming/ttf2fft.tar.gz

 

Le site de ming :http://ming.sourceforge.net/

 

Remerciements.

J'en profite pour remercier cyruss qui gère le site depuis plusieurs années et je vous conseille son livre sur lequel j'ai fait un peu de relecture : "PHP 5 avancé" aux editions Eyrolles.
Allez hop un petit logo pour lui faire un peu de pub :
Image

Retour à l'accueil des articles