Des palettes d'outils modulaires et détachables

Jim DORRANCE

Les commandes LIRE RECT OBJET, DEPLACER OBJET, et CHOIX VISIBLE permettent au développeur de repenser sa manière de mettre en application des interfaces. Il est possible de grouper des objets et de traiter le groupe lui-même comme élément d'interface. ♪

- Titre : Des palettes d'outils modulaires et détachables

- Auteur : Jim DORRANCE

- Parution : 1 avril 2004

- Licence : Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.

Sommaire

- I. Introduction

- II. Fonctionnalités

- III. La Base Demo: Constantes

- IV. La Base Demo: Sur Ouverture

- Le Process SplashScreen

- Le Process Palette

- La Méthode projet Palettes_Init

- Le Process Demo

- Le Process Picker

- La Méthode Projet PopUpPicker

- Cacher / Montrer la Palette

- Dessin des « Pickers » dans la palette

- La Méthode Projet FM_

- La Méthode Projet OM_

- V. Conclusion

- VI. Bases exemples

I - Introduction

Les palettes d'outils sont un standard dans beaucoup d'applications.

Des palettes sont associées à une « fenêtre contenante », c'est-à-dire une fenêtre contenant l'information éditable.  La palette aide l'utilisateur à éditer ou en formater le contenu.

Des palettes d'outils sont souvent mises dans une fenêtre à gauche d'une « fenêtre contenante » ou au-dessus de la « fenêtre contenante », sous la barre de titre. Ces positions évitent les conflits avec des commandes standards de fenêtre.

Si la palette appartient à la « fenêtre contenante », l'utilisateur a moins de place pour le contenu, particulièrement sur un petit écran. En outre des options de la palette peuvent être cachées si l'utilisateur rend la fenêtre plus petite.

L'utilisation des boutons de triangle de déploiement avec une palette dans sa propre fenêtre est une solution pour contrôler efficacement l'espace de bureau. Il vous permet également de présenter les choix les plus fréquents de l'utilisateur tout en cachant des choix plus complexes ou l'information additionnelle.

Cette note technique décrira comment créer les palettes modernes.

II - Fonctionnalités

Nous voudrions associer une palette de formatage à une « fenêtre contenante ».

Quand la « fenêtre contenante » est au premier plan, la palette devrait être visible. Quand la « fenêtre contenante » n'est pas au premier plan, la palette devrait disparaître. La première fois que la palette s'ouvre, seules les options de police devraient être déployées.

L'utilisateur devrait pouvoir glisser et déposer les zones dans la palette à sa convenance. Ici l'énumération d'expressions a été déplacée en haut de la palette:

L'utilisateur devrait pouvoir individuellement cacher / déployer  chaque zone :

Quand une zone est contractée, l'utilisateur doit avoir accès aux fonctionnalités de la zone par un Popup :

Et il serait intéressant de pouvoir « détacher » les zones et les montrer dans leur propre fenêtre.

III - La Base Demo: Constantes

Dans une Note Technique précédente, nous avons montré comment créer des constantes prédéfinies par programmation. La base Demo utilise des constantes créées par la méthode projet Ks_.

Ces constantes sont :

`
` TYPES  DES PROCESS: SÉLECTEURS POUR DES MÉTHODES FORMULAIRE ET DES MÉTHODES OBJET
`
kProcType_SplashScreen
kProcType_Demo
kProcType_Palette
kProcType_Picker
kProcType_PopUpPicker
`
`PALETTES: LES DIFFÉRENTES PALETTES EMPLOYÉES PAR LA BASE DE DONNÉES
`
kPalette_NoPalette
kPalette_DemoPalette
`
` TYPES DES PICKERS: LES DIFFÉRENTES ZONES DE LA PALETTE
`
kPickerType_Phrases
kPickerType_Fonts
kPickerType_RGB
`
`NOMS DES PICKER: LE PRÉFIXE ALPHA POUR DES OBJETS DANS LA PALETTE
`
kPickerLabel_Phrases
kPickerLabel_Fonts
kPickerLabel_RGB
`
`AUTRES Ks: LA HAUTEUR DE LA BARRE DE TITRE
`
kPalette_HeaderHeight
`
`SELECTEURS POUR Alert_
`
kAlert_BadParamCount

IV - La Base Demo: Sur Ouverture

La base Demo initialise des variables interprocess et crée 3 process au démarrage.

1. Compiler_InterProcess

3. `

4. `

5. <>Process_SplashScreen := Nouveau process(  "SplashScreen_";32*1024;"$SplashScreen")

6. <>Process_Palette:=Nouveau process("Palettes_";32*1024;"$Palette")

8. <>Process_Demo:=Nouveau process("Demo_";32*1024;"$Demo")

Le Process SplashScreen

Le process SplashScreen récupère son ID et l'affecte à la variable interprocess <>Process_SplashScreen.
Le process SplashScreen initialise alors des variables process et affecte deux variables, theProcessType et thePalette avec des constantes prédéfinies.

TheProcessType sera employé comme sélecteur dans des méthodes formulaire et des méthodes objet.

ThePalette contient la palette à associer à ce process. Dans cette base exemple, il y a 2 constantes prédéfinies:  kPalette NoPalette et kPalette DemoPalette. L'affectation de kPalette_NoPalette à la variable process ThePalette indique qu'aucune palette ne doit être montrée quand le process de SplashScreen est au premier plan.

Un dialogue de bienvenue simple est alors affiché :

1. <>Process_SplashScreen:=Numero du process courant

3. `

4. Compiler_Process

5. `

6. theProcessType:=kProcType_SplashScreen

7. thePalette:=kPalette_NoPalette

8. `

9. C_ENTIER LONG($W;$H)

10. LIRE PROPRIETES FORMULAIRE([Table 1];"SplashScreen";$W;$H)

11. `

12. C_ENTIER LONG($L;$T;$R;$B)

13. $L:=((Largeur ecran-$W)/2)

14. $T:=((Hauteur ecran-$H)/3)

15. $R:=$L+$W

16. $B:=$T+$H

17. `

18. Creer fenetre($L;$T;$R;$B;3)

19. DIALOGUE([Table 1];"SplashScreen")

21. FERMER FENETRE

Le Process Palette

Le process Palette récupère son ID et l'affecte à la variable interprocess <>Process_ Palette.
Le process Palette initialise alors des variables process et affecte deux variables, theProcessType et thePalette avec des constantes prédéfinies.

TheProcessType sera employé comme sélecteur dans des méthodes formulaire et des méthodes objet.

La constante prédéfinie kPalette_NoPalette est affectée à la variable process ThePalette.  Le process de palette n'a pas d'autre palette associée à sa fenêtre.

La variable interprocess <>ThePalette est affectée avec la valeur contenue dans la variable process ThePalette.

Le process Palette fait maintenant une boucle jusqu'à ce que l'on quitte 4D. S'il y a une palette à montrer, les données nécessaires pour la palette sont initialisées, une fenêtre est ouverte et la palette montrée. Sinon, aucun dialogue n'est montré et le processus est suspendu.

1. <>Process_Palette:=Numero du process courant

3. `

4. Compiler_Process

5. `

6. theProcessType:=kProcType_Palette

7. thePalette:=kPalette_NoPalette

8. <>thePalette:=thePalette

9. `

10. theEnd:=Faux

11. Repeter

12. `

13. thePalette:=<>thePalette

14. Si (<>thePalette=kPalette_NoPalette )

15. `

16. SUSPENDRE PROCESS(<>Process_Palette)

17. `

18. Sinon

19. `

20. Palettes_Init_ (kPickerType_Fonts ;kPickerType_Phrases ;kPickerType_RGB )

21. `

22. Repeter

23. Si (Chercher dans tableau(<>arPicker_IsThere;Vrai)>0)

24. Palettes_Window

25. DIALOGUE([Table 1];"Palette")

26. FERMER FENETRE

27. Sinon

28. <>thePalette:=kPalette_NoPalette

29. Fin de si

30. Jusque (thePalette#<>thePalette) | (theEnd) | (<>theEnd)

31. `

32. Fin de si

33. `

35. Jusque (theEnd) | (<>theEnd)

La Méthode projet Palettes_Init

La méthode  Palette_Init reçoit comme paramètres des constantes prédéfinies des zones qui doivent être incluses dans la palette et leur ordre d'inclusion.

La base demo a trois « Pickers », un « Picker » de couleur de RVB (kPickerType_Phrases), un « Picker » de police (kPickerType_Fonts), et un « Picker » d'expressions (kPickerType_Phrases).

Des tableaux interprocess contiennent l'information nécessaire permettant à chaque « Picker » de fonctionner.

Le type du « Picker » : <>arPicker_Type{theElement}.
Si le « Picker » est dans la palette : <>arPicker_IsThere{theElement}.
Si le carreau du « Picker » est caché/montré : <>arPicker_IsOpen{theElement}.
Le préfixe alpha des objets appartenant au « Picker » : <>arPicker_PreFix{theElement}.
La hauteur de la zone du « Picker » : <>arPicker_Height{theElement}.
Si le « Picker » est dans sa propre fenêtre : <>arPicker_Process{theElement}.
Un pointeur sur le bouton du caché/montré : <>arPicker_bHideShow{theElement}.
Un pointeur sur le bouton de Glisser/Déposer : <>arPicker_bDrag{theElement}.
Un pointeur sur le bouton de Popup : <>arPicker_bPopUp{theElement}.

Les données pour le « Picker » sont initialisées par la méthode projet Picker_Init.

Le Process Demo

TheProcessType sera employé comme sélecteur dans des méthodes formulaire et des méthodes objet.

Cette fois ThePalette contient le kPalette_DemoPalette, la palette à associer à ce process.

Un DIALOGUE est alors dessiné, quoique caché.

1. <>Process_Demo:=Numero du process courant

3. CACHER PROCESS (<>Process_Demo)

4. `

5. Compiler_Process

6. `

7. theProcessType:=kProcType_Demo

8. thePalette:=kPalette_DemoPalette

9. `

10. C_ENTIER LONG($W;$H)

11. LIRE PROPRIETES FORMULAIRE([Table 1];"Demo";$W;$H)

12. `

13. C_ENTIER LONG($L;$T;$R;$B)

14. $L:=((Largeur ecran-$W)/2)

15. $T:=((Hauteur ecran-$H)/3)

16. $R:=$L+$W

17. $B:=$T+$H

18. `

19. <>Window_Demo:=Creer fenetre($L;$T;$R;$B;Regular window ;"Demo")

20. DIALOGUE([Table 1];"Demo")

22. FERMER FENETRE

Le Process Picker

Un process « Picker » est créé pour chaque occurrence d'un « détaché » d'une zone de la palette.
Le process reçoit trois paramètres:  le « Picker » à montrer, et les coordonnées de la fenêtre à montrer.
Les deux drapeaux, theProcessType et thePalette sont affectés.

Le « Picker » est initialisé, et montré dans un dialogue.

1. C_ENTIER LONG($1)   `LE FORMULAIRE

3. C_ENTIER LONG($2)   `MOUSEV

4. C_ENTIER LONG($3)   `MOUSEH

5. `

6. `

7. Si (Nombre de parametres=3)

8. `

9. Compiler_Process

10. `

11. C_ENTIER LONG(thePicker;$MouseH;$MouseV)

12. thePicker:=$1

13. $MouseH:=$2

14. $MouseV:=$3

15. `

16. theProcessType:= kProcType_Picker

17. thePalette:= kPalette_NoPalette

18. `

19. Picker_Init (thePicker)

20. `

21. Picker_Window (thePicker;$MouseH;$MouseV)

22. DIALOGUE([Table 1];"Palette")

23. FERMER FENETRE

24. `

25. Sinon

26. Alert_ (Nom méthode courante;kAlert_BadParamCount )

28. Fin de si

La Méthode Projet PopUpPicker

La méthode projet PopUpPicker est appelée quand le bouton de PopUpPicker est cliqué dans la palette.

La méthode projet PopUpPicker installe la routine APPELER SUR EVENEMENT et ouvre une fenêtre pour montrer le « Picker » désiré.

1. C_ENTIER LONG($1)   `LE TYPE DE PICKER

3. C_ENTIER LONG($2)   `MOUSEV

4. C_ENTIER LONG($3)   `MOUSEH

5. `

6. `

7. Si (Nombre de parametres=3)

8. `

9. C_ENTIER LONG(thePicker;$MouseH;$MouseV;$theProcessType)

10. thePicker:=$1

11. $MouseH:=$2

12. $MouseV:=$3

13. `

14. $theProcessType:=theProcessType

15. theProcessType:=kProcType_PopUpPicker

16. `

17. <>Process_EventProcess:=Numero du process courant

18. `

19. PopUpPicker_Window (thePicker;$MouseH;$MouseV)

20. APPELER SUR EVENEMENT ("PopUpPicker_OnEventCall")

21. DIALOGUE([Table 1];"Palette")

22. APPELER SUR EVENEMENT ("")

23. FERMER FENETRE

24. `

25. theProcessType:=$theProcessType

26. <>Process_EventProcess:=0

27. `

28. Sinon

29. Alert_ (Nom méthode courante;kAlert_BadParamCount )

31. Fin de si

Le PopUpPicker_OnEventCall vérifie tous les clics de souris, et si un clic se produit en dehors de la fenêtre de PopUpPicker, l'événement est enlevé de la queue des événements, le process de PopUpPicker est appelé, et la fenêtre est fermée.

1. Si (MouseDown=1)

3. `

4. C_ENTIER LONG($h;$v;$State)

5. POSITION SOURIS ($h;$v;$State;*)

6. `

7. C_ENTIER LONG($Window)

8. $Window:= Chercher fenetre ($h;$v)

9. Si ($Window#<>theWindow)

10. FILTRER EVENEMENT

11. APPELER PROCESS (<>Process_EventProcess)

12. Fin de si

13. `

15. Fin de si

Cacher / Montrer la Palette

Quand la fenêtre  du process Demo est amenée au premier plan, l'événement formulaire Sur activation est reçu.
La méthode projet Palettes_Set est appelée avec la variable process thePalette comme paramètre. Cette méthode vérifie si la palette montrée est différente de la palette demandée, et si oui, le process Palette est appelé avec la variable interprocess <>thePalette mise à jour.

1. C_ENTIER LONG($1)   `PALETTE DEMANDEE

3. `

4. `

5. Si (Nombre de parametres=1)

6. Si (<>Process_Palette>0)

7. `

8. ` VERIFIE L'INTEGRITE DE LA REQUETE

9. `

10. C_ENTIER LONG($TheRequestedPalette)

11. $TheRequestedPalette:=$1

12. Si ($TheRequestedPalette<kPalette_NoPalette )

13. $TheRequestedPalette:=kPalette_NoPalette

14. Sinon

15. Si ($TheRequestedPalette>kPalette_theCount )

16. $TheRequestedPalette:=kPalette_NoPalette

17. Fin de si

18. Fin de si

19. `

20. `CHANGE LA PALETTE SEULEMENT SI NECESSAIRE

21. `

22. Au cas ou

23. `

24. : ($TheRequestedPalette=kPalette_NoPalette ) & (<>thePalette=kPalette_NoPalette )

25. `

26. : ($TheRequestedPalette=kPalette_NoPalette ) & (<>thePalette>kPalette_NoPalette )

27. <>thePalette:=$TheRequestedPalette

28. REACTIVER PROCESS (<>Process_Palette)

29. APPELER PROCESS (<>Process_Palette)

30. `

31. : ($TheRequestedPalette=<>thePalette)

32. MONTRER PROCESS (<>Process_Palette)

33. `

34. : (<>thePalette=kPalette_NoPalette ) & ($TheRequestedPalette>kPalette_NoPalette )

35. <>thePalette:=$TheRequestedPalette

36. MONTRER PROCESS (<>Process_Palette)

37. REACTIVER PROCESS (<>Process_Palette)

38. `

39. : ($TheRequestedPalette#<>thePalette)

40. <>thePalette:=$TheRequestedPalette

41. APPELER PROCESS (<>Process_Palette)

42. `

43. Fin de cas

44. `

45. Fin de si

46. Sinon

47. Alert_ (Nom méthode courante; kAlert_BadParamCount )

49. Fin de si

Dessin des « Pickers » dans la palette

Le formulaire « Palette » contient tous les objets nécessaires pour dessiner les « Pickers ». La page 0 contient les objets d'interface et une simple variable pour gérer le Glissé /Déposé.

Dans une base de données complexe, il serait intéressant d'avoir plusieurs formulaires, avec pour chacun les objets nécessaires pour un type spécifique de palette.

La page 1 contient les objets actifs nécessaires pour faire fonctionner la palette.

Quand la palette est dessinée, pour chaque « Picker » montré dans la palette, les objets des « Pickers » sont déplacés à leur emplacement correct. Quelques éléments sont cachés ou montrés, cela dépend de l'état du sémaphore Hide/Show du « Picker ».

Quand un « Picker » est dessiné dans sa propre fenêtre, comme dans un PopUpPicker, seulement les objets pour ce « Picker » sont déplacés. Tous les autres objets sont cachés avec la commande CHOIX VISIBLE.

1. C_ENTIER LONG($i;$thePicker;$thePickerCount;$theTop;$L;$T;$R;$B;$MoveH;$MoveV)

3. $thePickerCount:=Taille tableau(<>arPicker_Type)

4. `

5. C_BOOLEEN($Open)

6. $Open:=Faux

7. `

8. C_ALPHA(55;$PreFix)

9. `

10. ` OBTENEZ TOUS LES 'PICKERS' UTILISÉS EN PLACE, OUVERTS, EN COMMENÇANT AU DESSUS

11. `

12. $theTop:=0

13. Boucle ($thePicker;1;$thePickerCount)

14. $PreFix:=<>arPicker_PreFix{$thePicker}

15. Si (<>arPicker_IsThere{$thePicker})

16. `

17. CHOIX VISIBLE(*;$PreFix+"@";Vrai)

18. LIRE RECT OBJET(*;$PreFix+"Rect";$L;$T;$R;$B)

19. DEPLACER OBJET(*;$PreFix+"Drag";$L+2;$T+2;$R-2;$B-2;*)

20. CHOIX VISIBLE(*;$PreFix+"Rect";Faux)

21. $MoveH:=0-$L

22. $MoveV:=0-($T-$theTop)

23. DEPLACER OBJET(*;<>arPicker_PreFix{$thePicker}+"@";$MoveH;$MoveV)

24. $theTop:=$theTop+($B-$T)-1

25. `

26. $Open:=<>arPicker_IsOpen{$thePicker}

27. CHOIX VISIBLE(*;$PreFix+"OpenPict";$Open)

28. CHOIX VISIBLE(*;$PreFix+"ClosedPict";Non($Open))

29. CHOIX VISIBLE(*;$PreFix+"PopUp";Non($Open))

30. CHOIX VISIBLE(*;$PreFix+"PopUpPict";Non($Open))

31. `

32. Sinon

33. DEPLACER OBJET(*;<>arPicker_PreFix{$thePicker}+"@";MAXENT ;MAXENT )

34. CHOIX VISIBLE(*;$PreFix+"@";Faux)

35. Fin de si

36. Fin de boucle

37. `

38. ` POUR CHAQUE '"PICKER"', SI 'PICKER' NON OUVERT, ON CACHE LA ZONE DE CONTENU ET

39. ` DEPLACE LES 'PICKERS' DU DESSOUS

40. `

41. Boucle ($thePicker;1;$thePickerCount)

42. Si (<>arPicker_IsThere{$thePicker})

43. Si (Non(<>arPicker_IsOpen{$thePicker}))

44. $PreFix:=<>arPicker_PreFix{$thePicker}

45. $MoveV:=0-<>arPicker_Height{$thePicker}

46. `

47. ` ON VERIFIE  LA TAILLE DE LA VARIABLE  DRAG ET ON LA DEPLACE

48. ` (en fonction du statut du "PICKER", ouvert ou fermé)

49. `

50. LIRE RECT OBJET(*;$PreFix+"Drag";$L;$T;$R;$B)

51. DEPLACER OBJET(*;$PreFix+"Drag";$L;$T;$R;$B+$MoveV;*)

52. CHOIX VISIBLE(*;$PreFix+"_@";Faux)

53. `

54. Boucle ($i;$thePicker+1;$thePickerCount)

55. DEPLACER OBJET(*;<>arPicker_PreFix{$i}+"@";0;$MoveV)

56. Fin de boucle

57. `

58. Fin de si

59. Fin de si

61. Fin de boucle

La Méthode Projet FM_

La méthode projet FM_ est appelée à partir de tous les formulaires.
Puis FM_ appelle la méthode projet appropriée suivant le type du process.

L'événement Sur chargement est celui où les objets de « Picker » sont mis en place.

1. C_ENTIER LONG($1)   `EVENEMENT FORMULAIRE

3. `

4. Au cas ou

5. `

6. : (theProcessType=kProcType_Palette )

7. Palettes_FM ($1)

8. `

9. : (theProcessType=kProcType_Demo )

10. Demo_FM ($1)

11. `

12. : (theProcessType=kProcType_Picker )

13. Picker_FM ($1)

14. `

15. : (theProcessType=kProcType_PopUpPicker )

16. PopUpPicker_FM ($1)

17. `

18. : (theProcessType=kProcType_SplashScreen )

19. `

21. Fin de cas

La Méthode Projet OM_

La méthode projet  OM_ est appelée à partir de tous les objets actifs des formulaires.
Puis OM_ appelle la méthode projet appropriée suivant le type du process et objet appelés.

La méthode projet Picker_OM gère toutes les fonctionnalités des différents « Pickers » de la Palette.
Elle est également présente là où le bouton de Hide/Show (caché/montré), le bouton de PopUpPicker, et les routines de Glisser /Déposer sont gérés.

1. C_ENTIER LONG($1)   `EVENEMENT FORMULAIRE

3. C_POINTEUR($2)   `SELF

4. `

5. `

6. Si (Nombre de parametres=2)

7. `

8. C_ENTIER LONG($Event)

9. C_POINTEUR($Self)

10. $Event:=$1

11. $Self:=$2

12. `

13. Au cas ou

14. `

15. : (theProcessType=kProcType_SplashScreen )

16. `

17. : (theProcessType=kProcType_Palette )

18. Picker_OM ($Event;$Self)

19. `

20. : (theProcessType=kProcType_Demo )

21. Demo_OM ($Event;$Self)

22. `

23. : (theProcessType=kProcType_Picker )

24. Picker_OM ($Event;$Self)

25. `

26. : (theProcessType=kProcType_PopUpPicker )

27. PopUpPicker_OM ($Event;$Self)

28. `

29. Fin de cas

30. `

31. Sinon

32. Alert_ (Nom méthode courante;kAlert_BadParamCount )

34. Fin de si

V - Conclusion

Les commandes  LIRE RECT OBJET, DEPLACER OBJET, et CHOIX VISIBLE permettent au développeur de repenser sa manière de mettre en application des interfaces. Il est possible de grouper des objets et de traiter le groupe lui-même comme comme élément d'interface. Des éléments d'interface peuvent être organisés par des thèmes, avec les éléments de chaque thème sur un formulaire.

Pendant que les applications se développent en taille et complexité, une telle approche permet au développeur de créer les solutions modulaires aux problématiques qui se répètent. Dans la base Demo, la palette est montrée quand une fenêtre contenante est affichée. Elle pourrait également être appelée quand le curseur écrit entre dans une zone de texte, ou comme une zone popup associée à un bouton ; ou comme popup contextuel associé à un process d'APPELER SUR EVENEMENT.

VI - Bases exemples

Téléchargez les bases exemples :

base exemple Mac

base exemple Windows