FAQ dev Morph Squeak

From OFSET Wiki

Jump to: navigation, search

:: Espaces Squeak ::

accueil | programmer | outils et frameworks | applications Smalltalk | présenter Smalltalk | communauté | foire aux questions


Foire aux questions sur la programmation à l'aide du framework graphique Morph. Cette FAQ est construite pas à pas en fonction des échanges sur La liste francophone Squeak-fr et la liste beginners. Vous êtes bien sûr invité et encouragé à participer à son élaboration.

Contents

[edit] Comment supprimer l'accès aux halos d'un Morph ?

Dans votre Morph, surcharger la méthode wantsHaloFromClick comme ci-dessous :

MonMorph>>wantsHaloFromClick
   ^false

[edit] Comment ajouter des entrées dans le menu d'un Morph ?

Chaque Morph a un menu spécifique affichable par le halo rouge. Il est possible d'ajouter des items dans ce menu en surchargeant la méthode addCustomMenuItems:hand: de votre Morph :

addCustomMenuItems: menu hand: aHandMorph 
   super addCustomMenuItems: menu hand: aHandMorph.
   menu 
      add: 'mon item'
      target: self
      selector: #monTraitement

[edit] Comment programmer une méthode renvoyant une image ?

Le principe en trois étapes :

  • on charge l'image dans un SketchMorph;
  • on sauvegarde l'image en ascii dans un fichier (format textuel du Form contenu dans le SketchMorph);
  • on récupère le contenu du fichier (copier) et on l'intègre à une méthode qui retourne un Form (coller).

Pour reconstruire l'image, il suffit de créer un SketchMorph à partir du Form.

Voici le code à exécuter dans un workspace pour les trois étapes :

| s sketch |

" on cree un SketchMorph à partir du contenu du fichier png"
sketch := SketchMorph fromStream:  (FileStream readOnlyFileNamed: 'folder_red_open.png').

" on a besoin d'un stream pour stocker le Form de l'image au format textuel"
s := WriteStream on: String new.

" on écrit le Form de l'image dans le stream avec #storeOn: "
sketch form storeOn: s.

" on cree un fichier texte "
(FileStream newFileNamed: 'folder-red-open.txt') nextPutAll: s contents; close.

Voilà, dans le fichier folder-red-open.txt on a l'encodage ascii du Form. Voici un extrait de ce fichier :

(Form
	extent: 32@32
	depth: 32
	fromArray: #( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1101400586  
....
251658240 50331648 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
	offset: 0@0)

Il reste plus qu'à coder la méthode qui retourne le Form:

folderRedOpenForm
  ^ (Form
	extent: 32@32
	depth: 32
	fromArray: #( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1101400586  
....
251658240 50331648 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
	offset: 0@0)

Pour créer le SketchMorph :

folderRedOpenSketch
    ^ SketchMorph withForm: self folderRedOpenForm

[edit] Comment positionner des morphs avec des bordures égales ?

Je souhaite placer 3 morphs en ligne dans un morph plus grand (un tableau à 3 colonnes), de telle sorte que l'espace entre les morphs et les bordures soient égaux.

La seule manière que j'ai trouvé pour réaliser ce placement est d'utiliser 4 morph "espace". Cette technique donne le résultat escompté mais existe t'il un moyen d'arriver au même résultat sans utiliser ces morphs supplémentaires ?

| contener rect1 rect2 rect3 space1 space2 space3 space4 |
   contener := Morph new
      extent: 300@300;
      color: Color black;
      layoutPolicy: (TableLayout new);
      listDirection: #leftToRight;
      listCentering: #justified;                                                 
      wrapCentering: #center.
   space1 := Morph new
      hResizing: #spaceFill;
      color: Color transparent.
   space2 := Morph new
      hResizing: #spaceFill;
      color: Color transparent.
   space3 := Morph new
      hResizing: #spaceFill;
      color: Color transparent.
   space4 := Morph new
      hResizing: #spaceFill;
      color: Color transparent.      
   rect1 := RectangleMorph new
      extent: 50@20;
      color: Color red.
   rect2 := RectangleMorph new
      extent: 50@20;
      color: Color blue.
   rect3 := RectangleMorph new
      extent: 50@20;
      color: Color green.
   contener addMorph: space1;
      addMorph: rect1 ;
      addMorph: space2;
      addMorph: rect2;
      addMorph: space3;
      addMorph: rect3;
      addMorph: space4;
      openInWorld. 
  • En ajoutant listSpacing: #equal; au contener ça peut aider, mais tu n'as pas la bordure
  • Voici une version un peu simplifiée mais qui ne change pas grand chose.
| contener rect1 rect2 rect3 vide |
   contener := AlignmentMorph new   "TableLayout par défaut"
      color: Color black;
      layoutInset: 0;   "espace bords intérieurs"
      hResizing: #shrinkWrap;   "si tu veux que la dim horizontale soit calculée à partir du contenu"
      vResizing: #shrinkWrap.
   rect1 := RectangleMorph new  extent: 50 at 20; color: Color red.
   rect2 := RectangleMorph new extent: 50 at 20; color: Color blue.
   rect3 := RectangleMorph new extent: 50 at 20; color: Color green.
   vide := (RectangleMorph new extent: 50 at 20) color: Color transparent.
   contener addMorph:  vide;
      addMorph:  rect1 ;
      addMorph: (vide veryDeepCopy ) ;
      addMorph: rect2;
      addMorph: (vide veryDeepCopy) ;
      addMorph: rect3;
      addMorph: (vide veryDeepCopy) ;
      openInWorld.
  • on peut utiliser Morph>>#layoutInset: et Morph>>#cellInset: :
    • ces deux méthodes prennent un point en argument pour spécifier l'espace horizontal et vertical;
    • #layoutInset: est pour l'espace intérieur du conteneur
    • #cellInset: est pour l'espace intérieur entre les morphs contenus
   | conteneur rect1 rect2 rect3 |
   conteneur := AlignmentMorph newRow 
   color: Color black;
   layoutInset: 50 @ 0;
   cellInset: 50 @ 0;
   hResizing: #shrinkWrap;
   vResizing: #shrinkWrap.
   rect1 := RectangleMorph new  extent: 50 @ 20; color: Color red.
   rect2 := RectangleMorph new extent: 50 @ 20; color: Color blue.
   rect3 := RectangleMorph new extent: 50 @ 20; color: Color green.
   conteneur 
      addMorph:  rect1 ;
      addMorph: rect2;
      addMorph: rect3;
      openInWorld.


[edit] Comment utiliser les fontes, les couleurs et autres attributs dans du texte ?

Traduction de [1]. Pour un texte avec une fonte particulière, on utilise les classes Text et TextFontReference. Voici un premier exemple qui crée et ouvre un TextMorph avec un texte utilisant deux fontes :

| font1 font2 t1 t2 |
font1 := TextFontReference toFont: (StrikeFont familyName: 'BitstreamVeraSerif' size: 22).
font2 := TextFontReference toFont: (StrikeFont familyName: 'ComicSansMS' size: 18).
t1 := 'BitstreamVeraSerif (22) ' asText addAttribute: font1.
t2 := 'ComicSansMS (18)' asText addAttribute: font2.
(TextMorph new contents: t1 , t2) openInHand

On peut aussi utiliser des couleurs et des emphases. Pour les attributs couleur, on utilise la classe TextColor et pour les emphases, la classe TextEmphasis. Voici un exemple avec des fontes, du rouge et de l'italique :

| text size appendText |
text := Text
		string: 'Stephane '
		attributes: (Array
			with: TextColor red
			with: TextEmphasis italic
			with: (TextFontReference toFont: ((TextStyle named: #Accuat) fontNamed: 'Accuat18'))).
size := text size.
appendText := 'will survive'.
text
	addAttribute: (TextFontReference
	toFont: ((TextStyle named: #Accuve) fontNamed: 'Accuve12'))
	from: size + 1
	to: size + appendText size.
text append: appendText.
(TextMorph new contents: text) openInHand

Un dernier exemple sympatique qui ouvre un espace de travail dont le texte présente toutes les fontes disponibles :

| fontFamilies textStream currentFont fontSizes selectedFont |
fontFamilies := StrikeFont familyNames.
textStream := TextStream on: Text new.
fontFamilies
	do: [:symbol | 
		| fa | 
		currentFont := TextStyle named: symbol.
		fa := currentFont fontArray.
		fontSizes := fa	collect: [:fnt | fnt height].
		fontSizes
			do: [:s | 
				selectedFont := StrikeFont familyName: symbol size: s.
				textStream
					withAttribute: (TextFontReference toFont: selectedFont)
					do: [textStream nextPutAll: symbol; nextPut: $ ;nextPutAll: s asString;	cr]].
		textStream cr].
Workspace new contents: textStream contents; openLabel: 'Les fontes de Squeak'

[edit] Comment redimensionner une image ?

[edit] Avec ImageMorph, proportionnellement

| imgf |
imgf := ImageMorph new.
imgf image: (imgf image magnifyBy: 2).
imgf openInWorld.

magnifyBy: 2 pour doubler la taille, 0.5 pour diminuer de moitié, etc.

[edit] Avec ImageMorph, largeur et hauteur indépendantes

|img newForm|
img := ImageMorph new.
newForm := Form extent: (img image extent + (800@10)) depth:(img image depth).
(WarpBlt current toForm: newForm) sourceForm: (img image);   
        colorMap: (img image colormapIfNeededFor: newForm);
        cellSize: 1;
        combinationRule: 2;
        copyQuad: img image boundingBox innerCorners toRect: newForm boundingBox.
img image: newForm.
img openInWorld 


[edit] Avec SketchMorph

im:=SketchMorph new.
im form: (Form fromBinaryStream: 
      ((HTTPClient httpGet: 'www.k2r-riddim.net/public/images/avion.png'))).
im openInWorld.

im  height: 150
im width: 200


[edit] Comment créer un texte avec un lien hypertexte ?

| t m |
m := TextMorph new openInWorld.
t := Text string: 'hello ' attribute: TextColor red.
t append: (Text 
              string: 'click ici'
              attribute: (PluggableTextAttribute evalBlock: [Morph new openInWorld])).
m contents: t

Une variante dans une fenêtre acceptant des paragraphes de texte :

| t s |
s := ScrollableField new openInWorld.
t := Text string: 'hello ' attribute: TextColor red.
t append: (Text 
              string: 'click ici'
              attribute: (PluggableTextAttribute evalBlock: [Morph new openInWorld])).
s setMyText: t
Personal tools