HotCocoa est un librairie qui va vous permettre de générer et manipuler de manière simple une interface graphique (GUI) ainsi que ses interactions avec l’utilisateur directement depuis du code Ruby sans avoir besoin de passer par Interface Builder ou XCode.
Dans cette série d’articles sur HotCocoa, nous ne ferons rien d’extraordinaire mais nous couvrirons l’ensemble des bases nécessaires à l’écriture d’une application lourde en MacRuby sans utiliser Interface Builder. Ce tutoriel sera donc en plusieurs parties et aura pour but d’écrire une application capable de récupérer un flux RSS donné et d’afficher ses 5 dernières entrées.
Je vais ici considérer que vous avez déjà installé MacRuby grâce à notre introduction à MacRuby. Il ne nous reste donc qu’à installer HotCocoa. Auparavant, HotCocoa faisait partie intégrante de la distribution MacRuby mais c’est maintenant devenu un gem. Cette indépendance permet à l’équipe de HotCocoa d’accepter des contributions et d’évoluer plus rapidement.
Il nous faut donc lancer la commande suivante :
sudo macgem install hotcocoa
Nous avons maintenant accès à un nouveau binaire hotcocoa
qui va nous permettre de créer la structure de base de notre projet.
Créons donc notre arborescence de base :
hotcocoa SynbiozFeeds
Une fois notre arborescence créée, nous pouvons nous déplacer dans le répertoire SynbiozFeeds
et utiliser la commande macrake. Cette commande va lancer la tâche Rake par défaut qui a pour but de construire et démarrer l’application. Une fenêtre de type “Hello World” devrait apparaitre.
Quand vous utiliser MacRuby, pensez bien à utiliser tout ses outils dédiés : macrake, macirb, macgem et macruby.
Vous devez maintenant avoir, dans votre répertoire, un exécutable nommé SynbiozFeeds.app. Cet exécutable peut être lancé comme tout autre application Mac avec un double-clic. Il est nécessaire que le poste qui lance l’exécutable soit équipé de MacRuby. Il est également possible de compiler votre logiciel pour qu’il embarque MacRuby et puisse donc être exécuté sur une machine ne disposant pas de MacRuby mais nous verrons cela plus tard.
La structure de notre projet MacRuby / Cocoa est la suivante :
Le fichier Rakefile nous permet de lancer des tâches telles que la compilation de l’application, le nettoyage des fichiers compilés, la génération d’une version embarquant MacRuby ou tout simplement le lancement de l’exécutable.
Le fichier build.yml contient quant à lui des informations utilisées par HotCocoa pour construire l’application. On y trouvera le nom de l’application, la version, l’icône, l’emplacement des sources.
Les fichiers primordiaux pour l’écriture de notre application sont application.rb and menu.rb.
Le fichier menu.rb contient la définition du menu de notre application, par défaut voici à quoi il ressemble :
module HotCocoa
def application_menu
menu do |main|
main.submenu :apple do |apple|
apple.item :about, :title => "About #{NSApp.name}"
apple.separator
apple.item :preferences, :key => ","
apple.separator
apple.submenu :services
apple.separator
apple.item :hide, :title => "Hide #{NSApp.name}", :key => "h"
apple.item :hide_others, :title => "Hide Others", :key => "h", :modifiers => [:command, :alt]
apple.item :show_all, :title => "Show All"
apple.separator
apple.item :quit, :title => "Quit #{NSApp.name}", :key => "q"
end
main.submenu :file do |file|
file.item :new, :key => "n"
file.item :open, :key => "o"
end
main.submenu :window do |win|
win.item :minimize, :key => "m"
win.item :zoom
win.separator
win.item :bring_all_to_front, :title => "Bring All to Front", :key => "o"
end
main.submenu :help do |help|
help.item :help, :title => "#{NSApp.name} Help"
end
end
end
end
On voit que c’est ici que sont définis les noms de menus, les raccourcis clavier, la disposition des menus, etc.
Le sous-menu :apple est un menu spécial qui apparaitra sous la forme du nom de votre application comme on y est habitué dans les applications OS X.
Pour les autres menus, par défaut, les titres des menus seront la version capitalisée du symbole qui est passé en paramètre. Vous pouvez, si vous le souhaitez, définir un attribut :title => 'Mon menu'
pour utiliser un autre nom.
Le symbole que vous définissez dans les éléments de sous-menus seront utilisés pour générer le nom de la méthode qui sera invoquée lors d’un clic. Par exemple, pour le menu file.item :new
, la méthode on_new
sera utilisée pour la délégation. Si la méthode on_
n’existe pas dans votre code, l’élément du menu sera désactivé.
Le fichier application.rb généré par défaut est le suivant. Il est très court et facilement compréhensible.
require ‘rubygems’ require ‘hotcocoa’
# Replace the following code with your own hotcocoa code
class Application
include HotCocoa
def start
application :name => "SynbiozFeeds" do |app|
app.delegate = self
window :frame => [100, 100, 500, 500], :title => "SynbiozFeeds" do |win|
win << label(:text => "Hello from HotCocoa", :layout => {:start => false})
win.will_close { exit }
end
end
end
# file/open
def on_open(menu)
end
# file/new
def on_new(menu)
end
# help menu item
def on_help(menu)
end
# This is commented out, so the minimize menu item is disabled
#def on_minimize(menu)
#end
# window/zoom
def on_zoom(menu)
end
# window/bring_all_to_front
def on_bring_all_to_front(menu)
end end
Application.new.start
La librairie hotcocoa est chargée et on inclus la classe pour raccourcir notre code. L’application démarre grâce à la dernière ligne de code Application.new.start
.
La méthode Application#start crée un instance de notre application en définissant son titre.
On définit ensuite la délégation des événements vers notre propre classe. Notre classe va donc recevoir tous les appels aux méthodes de rappel (callbacks) effectués depuis notre application. Les appels aux méthodes on_*
du menu sont elles aussi concernées. Notre classe gère donc l’ensemble des interactions possibles depuis notre interface graphique.
À la ligne suivante, on crée une fenêtre qui sera positionnée à 100 pour l’axe des X et des Y. Ces valeurs sont relatives au coin inférieur gauche. Notre fenêtre aura une taille de 500 par 500. On spécifie le titre de la fenêtre grâce à l’option :title
. Nous aurions pu choisir uniquement la taille de la fenêtre sans définir son positionnement grâce à l’option :size => [500, 500]
et décider de la positionner au beau milieu du bureau grâce à l’option :center => true
.
L’ensemble des options disponibles peuvent être consultées directement depuis la documentation de Cocoa en regardant du côté de la classe NSWindow. Toutes les options disponible en Cocoa le sont également depuis HotCocoa.
Une fois la fenêtre créée, on y ajoute une étiquette (label) avec un texte, puis on demande à ce que l’application quitte lorsqu’on ferme la fenêtre.
Le callback will_close
est le nom utilisé dans HotCocoa, son équivalent Cocoa étant windowWillClose:
. La plupart des callbacks ont étés renommés pour adhérer au style de Ruby. Si vous voulez une liste complète, un simple coup d’oeil au code source des mappings HotCocoa vous apprendra tout. On voit par exemple, que pour la classe Window, on a une liste exhaustive à la fin du fichier window.rb
Cet article nous a permit d’effleurer la surface de HotCocoa et de l’écriture d’une application riche grâce à MacRuby. Maintenant que la structure de base de notre application est prête, dans un prochain article, nous verrons comment préparer notre interface pour quelle soit en mesure de recueillir des informations tirés de flux RSS dont l’adresse est saisie par l’utilisateur.
L’ensemble du code source utilisé pour cet article est disponible sur notre compte GitHub
L’équipe Synbioz.
Libres d’être ensemble.