STATUT : COMPLET

Téléchargement du tutoriel complet : tutoriel 1
Décompressez l'archive et copiez le dossier "1" dans "%scol%/partition/tutoriels/codes/" où %scol% est le dossier d'installation de Scol.
Ok pour toute version de Scol Windows, MacOS et Linux.


Mieux vaut lire à partir du début, c'est à dire dans la plupart des cas, de la fonction 'main', en bas de page.

Objectif :
Réalisation d'un mini-éditeur de texte par la prise en main de la base de l'API 2d de Scol, les fonctions et variables globales, les callbacks (fonctions réflexes).

Moyens :

  • Chargement d'un package
  • Utilisation des fonctions
  • Utilisation des variables globales
  • Création et gestion d'une fenêtre
  • Création et gestion d'objets texte et bouton simples
  • Utilisation de callbacks (fonctions réflexes)
  • Utilisation de boîtes de dialogue simples

Scol est sensible à la casse. Un nom de variable ou de fonction avec des casses différentes en crééra autant.
MaVariable est différent de Mavariable ou encore de maVarIable, etc
MaFonction est différente de Mafonction ou encore de MAfONCTION, etc
Si 'fun' est un mot clé Scol, 'Fun' ne l'est pas, etc

Bien entendu, il est tout à fait possible de faire un code beaucoup plus compact que celui présenté dans ce premier tutoriel. Des exemples de "compactage" de certains blocs d'instructions sont proposés dans les autres tutoriaux de cette série.

Ce package Scol est chargé grâce au script "launch.scol" présent dans le même dossier. La fonction 'main', située en fin de fichier, est la fonction primaire appelée par ce script.

"
_load "tutoriels/codes/1/tutoriel1.pkg"
main
"

La lecture (et l'exécution !) du code commence donc avec cette fonction ('main')

Lorsque le script "launch.scol" est lancé, une VM est d'abord créée dans un nouveau canal avec un environnement minimal depuis la VM primaire (le Scol engine).
Ensuite, les packages listés dans le script (ici un seul) sont chargés puis compilés à la volée et l'environnement de la VM est mis à jour. Une fois que tous les chargement sont OK et que la compilation s'est bien passée, la fonction à appeler est enfin exécutée.


DÉCLARATION des variables globales :

  • win : de type ObjWin est la fenêtre contenant l'interface graphique,
  • winw : de type I est la largeur de la fenêtre,
  • winh : de type I est la hauteur de la fenêtre,
  • text : de type ObjText est l'objet dans lequel le contenu d'un fichier texte chargé sera affiché,
  • btnLoad : de type ObjButton est l'objet bouton "Load file",
  • btnSave : de type ObjButton est l'objet bouton "Save file".

'typeof' est un mot-clef Scol qui permet de définir une variable globale en lui assignant un type précis

typeof win = ObjWin;;
typeof winw = I;;
typeof winh = I;;
typeof text = ObjText;;
typeof btnLoad = ObjButton;;
typeof btnSave = ObjButton;;

FONCTIONS

Une fonction est un ensemble d'instructions. Elle est définie par le mot clé 'fun' et se termine par un ';;'.
La syntaxe exacte est la suivante :

fun nom_de_la_fonction ( bloc_arguments ) =
	instruction_1;
	instruction_2;
	...
	instruction_n;;

L'indentation n'est pas obligatoire ...
Dans le bloc_arguments, les arguments sont séparés par des ',' :

fun maFonction(argument1, argument2, argument3)=
	instruction_1;
	instruction_2;
	instruction_3;;

Fonction callback appelée lors de la fermeture de la fenêtre.
La VM de cette petite application sera détruite : son processus n'existe plus et la mémoire est libérée.

Le type de cette fonction est : fun [ObjWin I] I
En effet, ses arguments sont

  • 'fenetre' -> ObjWin
  • 'paramuser' -> I (argument laissé à la discrétion du développeur)
  • et retourne un entier, donc I (_closemachine étant une fonction Scol)

fun end(fenetre, paramuser)=
	_closemachine;;

Fonction callback appelée lorsque la fenêtre est redimensionnée.
Les nouvelles valeurs de largeur et de hauteur sont affectées aux variables globales winw et winh (respectivement) et les différents objets composant l'interface sont redimensionnées pour garder l'ensemble homogène.
'_SIZEtext' et '_SIZEbutton' sont des fonctions Scol qui demandent l'objet à redimensionner, les nouvelles largeur et hauteur et la position du coin supérieur gauche par rapport à l'objet père (ici c'est la fenêtre 'win'). Elles retournent l'objet considéré.
Ces fonctions Scol sont donc du type fun [ObjText I I I I] ObjText et fun [ObjButton I I I I] ObjButton

Le type de cette fonction est : fun [ObjWin I I I] ObjButton
En effet, ses arguments sont

  • 'fenetre' -> ObjWin
  • 'paramuser' -> I
  • 'largeur' -> I
  • 'hauteur' -> I
  • et retourne l'objet 'btnSave' qui est de type ObjButton

fun resize(fenetre, paramuser, largeur, hauteur)=
	set winw = largeur;
	set winh = hauteur;
	_SIZEtext text winw-6 winh-26 3 3;
	_SIZEbutton btnLoad (winw-6)/2 20 3 winh-23;
	_SIZEbutton btnSave (winw-6)/2 20 (winw-6)/2+3 winh-23;;

Fonction callback appelée lorsqu'on a validé le choix d'un fichier à charger : le titre de la fenêtre est le chemin du fichier choisi et le contenu du fichier est affiché dans l'objet 'text'.
'_SETwindowName' est une fonction Scol permettant d'affecter un titre à une fenêtre. Elle retourne la même fenêtre. Son type est fun [ObjWin S] ObjWin
'_PtoScol' est une fonction Scol pour traduire un type P (référence de fichier en lecture seule) en un type S (le path du fichier). Son type est fun [P] S
'_SETtext' est une fonction Scol affectant un contenu de type S à un objet texte de type ObjText. L'ancien contenu s'il existait est écrasé. Elle retourne l'objet texte en question. Son type est fun [ObjText S] ObjText '_getpack' est une fonction Scol retournant le contenu d'un fichier donné sous forme de référence en lecture seule. Son type est fun [P] S

Le type de cette fonction est : fun [OpenBox I P] ObjText
En effet, ses arguments sont

  • 'dialogbox' -> OpenBox (l'objet boîte de dialogue de chargement de fichier qu'on vient de valider)
  • 'paramuser' -> I
  • 'fileread' -> P (le fichier choisi sous forme de référence en lecture seule)
  • et retourne un objet de type ObjText (l'objet 'text' dont le contenu vient d'être modifié)

fun load(dialogbox, paramuser, fileread)=
	_SETwindowName win _PtoScol fileread;
	_SETtext text _getpack fileread;;

Fonction callback appelée lorsqu'on clique sur le bouton "Load file".
Une boîte de dialogue standard de choix de fichier est alors affichée et la callback associée est définie.
_DLGOpenFile est une fonction Scol qui attend en argument le canal dans lequel elle doit être exécutée, sa fenêtre mère (qui peut ne pas exister mais ici ce sera la fenêtre 'win'), un dossier prédéfini dès l'ouverture ici à 'nil', donc ce sera à la racine de la partition active), un nom de fichier prédéfini s'il y a lieu et un filtre pour n'afficher que certains types de fichiers. Elle est donc du type fun [Chn ObjWin S S S] OpenBox
_DLGrflopen est une fonction Scol exécutée lorsque le choix d'un fichier est validé. Le paramètre utilisateur qui peut être de n'importe quel type est ici défini comme étant un entier I ('0'). Elle est donc de type fun [OpenBox fun [OpenBox I P] I] OpenBox

Le type de cette fonction est : fun [ObjButton I] OpenBox
En effet, ses arguments sont

  • 'bouton' -> ObjButton (le bouton sur lequel on a cliqué)
  • 'paramuser' -> I ('0')
  • et retourne un objet de type OpenBox (la boîte de dialogue de choix de fichier).

Remarque : dans des projets plus importants et lorsque le type renvoyé par la fonction n'a pas d'importance, mieux vaut alors renvoyé un entier en la terminant par un 0 (zéro). Comme il faut prendre de bonnes habitudes dès le départ, ce sera fait dès le tutoriel n°2 ! ;-)

fun cbLoad(bouton, paramuser)=
	_DLGrflopen
		_DLGOpenFile 
			_channel
			win
			nil
			nil
			"text\0*.txt\0pkg\0*.pkg\0scol\0*.scol\0\0"
		@load
		0;;

Fonction callback appelée lorsqu'on clique sur le bouton "Save file".
Une boîte de dialogue standard de choix de fichier est alors affichée et la callback associée est définie.
_DLGSaveFile est une fonction Scol qui attend en argument le canal dans lequel elle doit être exécutée, sa fenêtre mère (qui peut ne pas exister mais ici ce sera la fenêtre 'win'), un dossier prédéfini dès l'ouverture ici à 'nil', donc ce sera à la racine de la partition active), un nom de fichier prédéfini s'il y a lieu et un filtre pour n'afficher que certains types de fichiers. Elle est donc du type fun [Chn ObjWin S S S] SaveBox
_DLGrflsave est une fonction Scol exécutée lorsque le choix d'un fichier est validé. Le paramètre utilisateur qui peut être de n'importe quel type est ici défini comme étant un entier I ('0'). Elle est donc de type fun [SaveBox fun [SaveBox I P] I] SaveBox

Remarque : l'objet concerné par la callback (SaveBox) est créé lors de la définition de la callback. Les deux fonctions Scol sont imbriquées et on aurait pu le faire de façon distincte tel que cela a été fait lors de la création de l'interface graphique. Les deux méthodes se valent.
L'indentation qui améliore sensiblement la lecture et la compréhension du code.

Le type de cette fonction est : fun [ObjButton I] OpenBox
En effet, ses arguments sont :

  • 'bouton' -> ObjButton (le bouton sur lequel on a cliqué)
  • 'paramuser' -> I ('0')
  • et retourne un objet de type SaveBox (la boîte de dialogue de choix de fichier).

fun cbSave(bouton, paramuser)=
	_DLGrflsave
		_DLGSaveFile 
			_channel	// le canal
			win			// la fenêtre mère
			nil			// le path par défaut à l'ouverture de la boîte de dialogue
			nil			// le fichier par défaut
			"text\0*.txt\0pkg\0*.pkg\0scol\0*.scol\0\0"		// le filtre
		@save			// la callback associée à cette boîte de dialogue
		0;;				// le paramètre utilisateur

Fonction créant les callbacks associés à divers objets graphiques de l'application.
Ces fonctions réflexes sont précédées d'un '@'.

  1. La fenêtre 'win' : lorsqu'on décide de la détruire (x en haut à droite) et lorsqu'on la redimensionne;
  2. Le bouton 'btnLoad' : lorsqu'on clique dessus;
  3. Le bouton 'btnSave' : lorsqu'on clique dessus.

Le type de cette fonction est fun [] I

fun createCallback()=
	// Callback à appeler lorsque la fenêtre est détruite
	_CBwinDestroy 
		win 		// l'objet concerné
		@end 		// la callback associée à cet objet
		0;			// le paramètre utilisateur
	// Callback à appeler lorsque la fenêtre est redimensionnée
	_CBwinSize 
		win 
		@resize 
		0;
	// Callback à appeler lorsque le bouton "Load file" est cliqué
	_CBbutton 
		btnLoad 
		@cbLoad 
		0;
	// Callback à appeler lorsque le bouton "Save file" est cliqué
	_CBbutton 
		btnSave 
		@cbSave 
		0;
	0;;				// On termine par 0 afin de ne pas se préoccuper d'une incompatibilité de type éventuelle

Fonction créant l'interface graphique : une fenêtre, un objet texte et deux boutons. Une fois créée, on définira les callbacks associées à chacun d'eux.

Cette fonction prend un argument ('title'). Les arguments sont toujours placés après le nom de la fonction mais avant le symbôle '=' et sont placés entre parenthèses, chacun étant séparé par des virgules.
Chaque instruction se termine par un ';' et toute fonction se clôt par ';;'.

'_channel' est une fonction Scol renvoyant le canal courant.

Son type est fun [S] I
En effet, en argument, elle prend :

  • 'title' -> S (le titre que prendra la fenêtre)
  • et retourne 0 (le résultat de la fonction 'createCallback' appelée en dernier)

fun createInterface(title)=
	// Création de la fenêtre
	set win = _CRwindow 			// fonction Scol créant une fenêtre
				_channel 			// le canal dans lequel elle doit être créée
				nil 				// fenêtre mère (ici aucune d'où 'nil')
				0 0 winw winh 		// sa position (x y) par rapport à l'écran ou à la fenêtre mère, sa largeur et sa hauteur
				WN_NORMAL 			// ses flags de création (cf doc html)
				title;				// son titre
	// Création de l'objet texte
	set text = _CReditText  		// fonction Scol créant un objet texte éditable de type ObjText
				_channel 			// le canal dans lequel il doit être créé
				win 				// la fenêtre dans laquelle il sera créé
				3 3 winw-6 winh-26 	// sa position dans la fenêtre, sa largeur et sa hauteur
				ET_DOWN|ET_ALIGN_LEFT|ET_HSCROLL|ET_VSCROLL	// ses flags de création (cf doc html)
				nil;				// son contenu (ici, aucun au départ, d'où le 'nil')
	// Création d'un bouton
	set btnLoad = _CRbutton			// fonction Scol créant un objet texte de type ObjButton
					_channel		// le canal dans lequel il doit être créé
					win				// la fenêtre dans laquelle il sera créé
					3 winh-23 (winw-6)/2 20	// sa position dans la fenêtre, sa largeur et sa hauteur
					0				// ses flags de création (cf doc html)
					"Load file";	// Le nom affiché
	// Création d'un second bouton (même manip que le premier)
	set btnSave = _CRbutton
					_channel
					win
					(winw-6)/2+3 winh-23 (winw-6)/2 20
					0
					"Save file";
	// Appel de la fonction créant les callbacks associées.
	// Cet appel n'est pas obligé, on peut les définir directement dans cette fonction-ci
	// mais c'est plus propre ainsi.
	createCallback;;

Fonction qui appelée par le script de lancement du programme (launch.scol dans le même dossier que ce fichier).

Les valeurs de deux variables globales sont définies et on appelle la fonction devant créer l'interface graphique. Cette fonction nécessite un argument sous forme de chaîne (type S). Elle est définie AVANT pour ne pas provoquer d'erreur lors de la compilation.
De manière générale et sauf cas particulier il convient de toujours définir une fonction avant de l'appeler.

'set' est une fonction Scol assignant une valeur à une variable (locale ou globale). La discussion sur la notion d'effet de bord est sans intérêt ici. Se reporter au "Tutoriel Scol" version 3.0 de Sylvain Huet si nécessaire.

Cette fonction 'main' est de type fun [] I
En effet, ici elle ne prend pas d'argument et retourne 0 (zéro) qui est elle-même la valeur retournée par 'createInterface'.

fun main()=
	set winw = 500;
	set winh = 400;
	createInterface "Tutoriel 1";;