BUG? l'argument 'face des fonctions 'detect et 'insert-event-func est le screen-face!
françois20-Feb-2011/12:48:59+1:00
Bonjour,

Je rencontre une grosse difficulté dans l'implémentation du comportement des menus.

La documentation rebol explique que la commande insert-event-func prend comme argument une fonction dont les paramètres sont [face event].
Je m'attendais à ce que rebol passe dans 'face l'objet sur lequel l'événement a effectivement eu lieu, comme un bouton par exemple. Ors, il n'en est rien. Le paramètre 'face est en faite le system/view/screen-face, ce qui totalement sans intérêt!

Dans le cas qui me concerne, j'espérais en fait pouvoir identifier la face qui a reçu l'événement pour l'exclure d'un traitement global. En fait, je veux simuler le comportement standard des menus: lorsqu'un clic survient en dehors des menus, ceux-ci doivent tous être fermés. Si un clic a lieu sur le titre d'un menu, tous les autres doivent être fermés avant d'ouvrir le menu cliqué, etc...

Mais malheureusement, comme l'argument face n'est pas l'objet qui a reçu l'évèvement, cela complique grandement le traitement.

Ma question: d'après-vous, est-ce une fonctionnalité ou un bug? Si c'est un bug, qui dans le petite communauté francophone, pourrais faire du lobbying pour une correction rapide?

Merci
coccinelle20-Feb-2011/14:14:05+1:00
Il ne faut pas utiliser face qui est effectivement screen-face, mais event/face qui lui contient l'objet qui a reçu l'événement.
françois20-Feb-2011/14:21:40+1:00
maheureusement non, coccinelle, event/face contient le fenêtre...
françois20-Feb-2011/17:46:25+1:00
Bon,

selon moi, le fait que l'argument face pointe vers system/view/screen-face est totalement inutile. Il serait bien plus utile que ce paramètre soit en fait la FACE qui est la cible réelle de l’évènement.

Par contre, le fait que event/face pointe vers la FACE de la fenêtre dans laquelle l’évènement a eu lieu peut être fort utile pour restreindre la gestion globale des évènements à une fenêtre particulière.

Pour moi, le fait que l'argument 'face pointe vers screen-face s'apparente plus à un bug qu'à une fonctionnalité utile!
Philippe20-Feb-2011/21:25:22+1:00
Salut,

insert-event-func comme son opposée remove-event-func à son intérêt pour gérer des évenements au niveau global.
Tu peux avoir plus de détails ici :
http://www.rebol.com/docs/view-face-events.html

Sinon, peux-tu mettre un exemple de code ?
Il existe aussi des libs de menus en rebol (Cyphre).

===Philippe
François20-Feb-2011/21:34:26+1:00
Bonjour Philippe

J'ai lu de lon en large la documentation de View

J'ai finalement trouvé une solution de contournement à mon soucis et voici un exemple complet de gestion de menus:
#!/opt/rebol/rebview

REBOL [
	title: "Sample Menu"
	author: "François Vanzeveren"
	file: %menu.r
	version: 0.0.1
	history: [
		0.0.1 20-Feb-2011 "This file is created"
	]
]

g_menus: copy []
g_menus-titles: copy []

;======================================================================
; Gestion du comportement des menus:
;	1) Si un click a lieu en dehors de tout menu, il faut fermer tous
;		les menus ouverts
;	2) Si un click a lieu sur un menu (le titre ou le corps du menu), 
;		il faut fermer tous les autres menus, mais garder le menu
;		sélectionné (càd clické) ouvert (le titre et le corps) pour 
;		permettre son traitement en aval du flux du traitement des 
;		événements.
;
;======================================================================
close-menus-event: function [face event] [menus menus-titles index] [

	; 'face est un simple pointeur vers system/view/screen-face --> sans intérêt
	; 'event/face est un pointeur sur la FACE de la fenêtre dans laquelle 
	; l'événement a eu lieu, ce qui est intéressant pour restreindre
	; le périmètre d'application de la gestion globale des événements à une 
	; fenêtre en particulier (cfr ci-dessous).
	; 
	; Bref, nous devons mettre en place une solution de contournement pour 
	; retrouver la FACE qui a effectivement reçu l'événement!
	
	menus: copy g_menus
	menus-titles: copy g_menus-titles
	index: none 

	if all [equal? event/face main-win equal? event/type 'down] [
		foreach f event/face/pane [
			if all [f/show? greater-or-equal? event/offset/x f/offset/x
					greater-or-equal? event/offset/y f/offset/y 
					lesser-or-equal? event/offset/x add f/offset/x f/size/x
					lesser-or-equal? event/offset/y add f/offset/y f/size/y]
			[
				; Le click a eu lieu sur une FACE visible
				; Vérifions si le FACE clické est un menu (titre ou corps)
				index: find menus-titles f
				if none? index [index: find menus f]
				if not none? index [index: index? index]
				break
			]
		]
		if not none? index [
			; La FACE sur laquelle l'événement souris a eu lieu est un menu.
			; Nous le retirons de la liste des menus à fermer immédiatement
			remove at menus index
			remove at menus-titles index
		]
		
		foreach m menus-titles [
			m/state: false ; le titre du menu retourne à l'état de non sélectionné.
		]
		hide menus
		show g_menus-titles
	]
	event
]


insert-event-func :close-menus-event

main-win: layout/origin [
	; menu bar
	across
	space 0
	file-menu-title: toggle "Fichier" [
		either true? face/state [show file-menu] [hide file-menu]
	]
	
	edit-menu-title: toggle "Edition" [
		either true? face/state [show edit-menu] [hide edit-menu]
	]
		
	help-menu-title: toggle "Aide" [
		either true? face/state [show help-menu] [hide help-menu]
	]
	
	; File menu
	file-menu: panel sky [
		origin 0x0
		space 1x1
		tt "Nouveau..." [
			request/ok "Vous avez sélectionné [Fichier/Nouveau...]"
			hide face/parent-face
			file-menu-title/state: false
			show file-menu-title
		]
		tt "Ouvrir..." [
			request/ok "Vous avez sélectionné [Fichier/Ouvrir...]"
			hide face/parent-face
			file-menu-title/state: false
			show file-menu-title
		]
		tt "Fermer" [
			request/ok "Vous avez sélectionné [Fichier/Fermer]"
			hide face/parent-face
			file-menu-title/state: false
			show file-menu-title
		]
		box 180x1 coal
		tt "Enregistrer" [
			request/ok "Vous avez sélectionné [Fichier/Enregistrer]"
			hide face/parent-face
			file-menu-title/state: false
			show file-menu-title
		]
		tt "Enregistrer sous..." [
			request/ok "Vous avez sélectionné [Fichier/Enregistrer sous...]"
			hide face/parent-face
			file-menu-title/state: false
			show file-menu-title
		]
		box 180x1 coal
		tt "Mise en page..." [
			request/ok "Vous avez sélectionné [Fichier/Mise en page...]"
			hide face/parent-face
			file-menu-title/state: false
			show file-menu-title
		]
		tt "Aperçu avant impression..." [
			request/ok "Vous avez sélectionné [Fichier/Aperçu avant impression...]"
			hide face/parent-face
			file-menu-title/state: false
			show file-menu-title
		]
		tt "Imprimer..." [
			request/ok "Vous avez sélectionné [Fichier/Imprimer...]"
			hide face/parent-face
			file-menu-title/state: false
			show file-menu-title
		]
		box 180x1 coal
		tt "Exporter..." [
			request/ok "Vous avez sélectionné [Fichier/Exporter...]"
			hide face/parent-face
			file-menu-title/state: false
			show file-menu-title
		]
		tt "Importer..." [
			request/ok "Vous avez sélectionné [Fichier/Importer...]"
			hide face/parent-face
			file-menu-title/state: false
			show file-menu-title
		]
		box 180x1 coal
		tt "Propriétés..." [
			request/ok "Vous avez sélectionné [Fichier/Propriétés...]"
			hide face/parent-face
			file-menu-title/state: false
			show file-menu-title
		]
		box 180x1 coal
		tt "Quitter" [
			quit
		]
	] edge [color: coal size: 1x1]
	
	do [
		file-menu/show?: false
		file-menu/offset: add file-menu-title/offset to-pair reduce [0 file-menu-title/size/y]
		append g_menus file-menu
		append g_menus-titles file-menu-title
	]
	
	; Edit menu
	edit-menu: panel sky [
		origin 0x0
		space 1x1
		tt "Annuler" [
			request/ok "Vous avez sélectionné [Edition/Annuler]"
			hide face/parent-face
			edit-menu-title/state: false
			show edit-menu-title
		]
		tt "Rétablir" [
			request/ok "Vous avez sélectionné [Edition/Rétablir]"
			hide face/parent-face
			edit-menu-title/state: false
			show edit-menu-title
		]
		box 195x1 coal
		tt "Couper" [
			request/ok "Vous avez sélectionné [Edition/Couper]"
			hide face/parent-face
			edit-menu-title/state: false
			show edit-menu-title
		]
		tt "Copier" [
			request/ok "Vous avez sélectionné [Edition/Copier]"
			hide face/parent-face
			edit-menu-title/state: false
			show edit-menu-title
		]
		tt "Coller" [
			request/ok "Vous avez sélectionné [Edition/Coller]"
			hide face/parent-face
			edit-menu-title/state: false
			show edit-menu-title
		]
		tt "Tout sélectionner" [
			request/ok "Vous avez sélectionné [Edition/Tout sélectionner]"
			hide face/parent-face
			edit-menu-title/state: false
			show edit-menu-title
		]
		box 195x1 coal
		tt "Préférences..." [
			request/ok "Vous avez sélectionné [Edition/Préférences...]"
			hide face/parent-face
			edit-menu-title/state: false
			show edit-menu-title
		]
	] edge [color: coal size: 1x1]

	do [
		edit-menu/show?: false
		edit-menu/offset: add edit-menu-title/offset to-pair reduce [0 edit-menu-title/size/y]
		append g_menus edit-menu
		append g_menus-titles edit-menu-title
	]
		
	; Help menu
	help-menu: panel sky [
		origin 0x0
		space 1x1
		tt "Contenu..." [
			request/ok "Vous avez sélectionné [Aide/Contenu...]"
			hide face/parent-face
			help-menu-title/state: false
			show help-menu-title
		]
		tt "A propos de..." [
			request/ok "Vous avez sélectionné [Aide/A propos de...]"
			hide face/parent-face
			help-menu-title/state: false
			show help-menu-title
		]
	] edge [color:coal size: 1x1]

	do [
		help-menu/show?: false
		help-menu/offset: add help-menu-title/offset to-pair reduce [0 help-menu-title/size/y]
		append g_menus help-menu
		append g_menus-titles help-menu-title
	]
] 0x0

view main-win

ldci21-Feb-2011/10:19:45+1:00
Une possibilité qui n'est pas très bien documentée dans Rebol 2 est d'utiliser face /changes et show face

exemples

face/changes: 'text ; permet de changer le titre de la face
face/changes: 'offset; permet un hardware scrolling
face/changes: 'activate ; rend la face active

Peut être intéressant pour les menus?

Login required to Post.


Powered by RebelBB and REBOL 2.7.8.4.2