r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[!REBOL3 GUI]

Cyphre
8-Jun-2011
[7155]
It's time to decide about propagation of events using actors in R3GUI 
so we would like to know your opinion on that.

example:
Let's have face A and face B which is inside face A.

Currently, when you click mouse button on the face B and the face 
B has defined ON-CLICK actor the event is fired to that actor.

If the face B have no ON-CLICK actor the event is not catched anywhere.


We got a request to checnge this so there are few possible options 
we could use:


1. If face B doesn't have ON-CLICK actor defined then propagate the 
event up to its parent face (in our case face A) and up until any 
ON-CLICK is found. (If the face B have ON-CLICK defined then the 
actor is executed and propagation stops here.) In other words the 
event propagation stops in the closest found ON-CLICK actor during 
the 'bubbling' of the event upwards.


2. Propagate the event from face B thru its parent face (in our case 
face A) and up to the topmost(Window) face. The propagation/bubbling 
is done by default and can be stopped in any ON-CLICK actor on the 
way upwards by returning 'stop-event(or any other chosen) keyword. 
(this is simmilar to the model used in HTML)


3. (current behaviour) Don't propagate the event. Just execute the 
ON-CLICK actor in face B in case it is defined. Programmer have to 
manually add event propagation code to the actor if event bubbling 
is required.


4. Don't propagate the event by default. But introduce PROPAGATE/BUBBLE-ACTORS 
(or any other chosen word) option field that can be set for each 
face. The option could hold block of actor names that should propagate/bubble 
the events up.


Please, keep in mind that chosen behaviour affects not only actors 
that handle user input but also actors like ON-INIT, ON-MAKE and 
any other possible actors in general.


Please post either your favorite from the above options or even any 
other possible solution you think is better. Thanks for your help.
Gregg
8-Jun-2011
[7156]
#4 is an extension to #3, and would be my first choice if #3 isn't 
enough. I generally don't like having to say "stop!" to avoid unexpected 
behavior. I don't know if #1 works well, though I think QNX Photon 
used it.


If the 'bubble option can be part of the style, then you can define 
buttons not to bubble on-click by default, but maybe 'text would, 
for example.
PeterWood
8-Jun-2011
[7157]
The approach outlined in #1 is similar to that employed by LiveCode 
(used to be called Revolution). It seems to be a good model. It additionally 
supports "user-defined" events in the same way.
Gregg
8-Jun-2011
[7158x2]
To stop bubbling, you just define an empty on-click handler I assume?
Or does it have to return a specific value to say it handled the 
event?
PeterWood
8-Jun-2011
[7160x3]
#2 seems the worst of both "worlds"
#3 seems clear and workable
#4 appears to lead to complexity
Yes to stop bubbling you define an empty event handler.
I am thankful that you aren't considering the DOM 2t option - some 
events bubble, some don't.
Ladislav
9-Jun-2011
[7163x2]
* I do agree with Peter that #3 is clear and workable. Accepting 
any of the alternatives would require (a lot of, I am afraid) code 
to stop  unsolicited bubbling.

* #4 appears to lead to complexity, and thus it may be the worst 
alternative
* #1 looks like the second best to me
* #2 looks like the second worst
Yes, the alternative "some events bubble, some don't" looks like 
worse than any of #1 to #4
Pekr
9-Jun-2011
[7165x5]
Just supppoting question - in R2 we were able to have "event filters" 
defined via insert-event-func. It allowed us to catch events going 
to subfaces. So my question is - if e.g. for #1, the event goes directly 
to face B, am I able to catch it, by inserting the filter into face 
A?

http://www.rebol.com/docs/view-face-events.html#section-14
I wonder if anyone uses reverse aproach - from top window, down to 
bottom face. Would be slow probably?
I do remember how QNX Photon used such a trick to share screen content. 
You defined X*Y area of the screen (imagine empty translucent face) 
and all events got via that "filter", so that you know what to send 
to target computer, and then the event was propagated to cause an 
action (at least that is how I understood it back then)
Hmm, I wonder if my Photon example is in contradition or in any relation, 
as having translucent face upon A->B does not make A->B being child 
of such a filter face ...
I am probably for #3 or #1. Just help me to brainstorm one case - 
what we have mostly wrong in REBOL, is pop-up handling. I mean - 
just recently e.g. when you "drag", and you move away from the face 
coordinates, the dragging stops. The same goes for the context menu 
etc - you have to be able to close the menu by clicking anywhere 
in the apps window. Which model fits best?
PeterWood
9-Jun-2011
[7170x2]
One of the attractions of #1 is that it makes it easy to implement 
"default handlers" at some point higher up the hierarchy. For example 
based upon an  "esc pressed event" (if one were to exist.) and you 
had designed a panel with four buttons. If you wanted to close the 
panel when the user pressed esc, you would simply have a single "handler" 
for the panel which would receive the event.


I'm sure that this isn't  the best example and apologise in advance 
for my ignorance of REBOL3-GUI and its common terms.
Perhaps a better example would be to allow a user to tab along a 
row of buttons. A single handler could be written for the button 
"container" that would handle tab presses instead of each button 
having a specific "handler".
Robert
9-Jun-2011
[7172]
With 3. you can simulate 1. The advantage of 3. is, that I can decide 
at what place the parent actor is called.


Which leads me to a question: Is 3. a call the parent actor, which 
returns, or do I just let the event flow and it will never return 
to my handler?
PeterWood
9-Jun-2011
[7173]
On the other hand with #3, this could be achieved by the buttons 
sharing a single event handler function.


The clairty that option #3 brings in that as you always have to specify 
what happens to an event would, for me, lead to a lower number of 
"head scratching" bugs.
Robert
9-Jun-2011
[7174]
Yes, 3. is explicit while 1. is implicit.
Rebolek
9-Jun-2011
[7175]
I prefer #1 and then #3.
Robert
9-Jun-2011
[7176]
Is there a way that we can use #1 and add a way that it can be overriden 
by #3 concept? So, everyone how don't require fine-grained handling, 
uses default bubbeling.
Rebolek
9-Jun-2011
[7177x2]
If bubbling is enabled by default, you just need to add an actor 
where you want to catch the event.
For example if I add image to button, with #3 I need to ad actor 
to image to catch click and send it to button. With #1 it's done 
automatically.
Cyphre
9-Jun-2011
[7179x2]
Rebolek, wht you mean by 'add image to button'?
So far it looks everyone is happy with the current behaviour (#3)?
Rebolek
9-Jun-2011
[7181]
It's just an example, image you want to add save icon to save button.
Cyphre
9-Jun-2011
[7182]
So can I translate as 'Image face inside Button face'?
Rebolek
9-Jun-2011
[7183]
exactly.
Cyphre
9-Jun-2011
[7184x2]
If yes, then in #1 case the event would be processed in the Image 
as well because image style have defined on-click actor no?
...and currently you cannot set actor to undefined state. So #1 wouldn't 
be too much useful, isn't it?
Rebolek
9-Jun-2011
[7186]
as I said, it's just an example
Cyphre
9-Jun-2011
[7187x2]
yes, I'm just trying to see what could be better on the #1
Personally I prefer also the  the current #3 behaviour but if we 
want to deal with more complex propagation I'd go with the #2 which 
gives really flexible control for some special cases but  as some 
of you noted it will be complex for event handling of the rest 95% 
of normal cases.
Henrik
9-Jun-2011
[7189]
is there any issue in propagating a larger number of different events? 
suppose you want to simply handle all events from an inside face.
Cyphre
9-Jun-2011
[7190x2]
When thinking  #3 vs. #1:

In the #3 case the propagation should be done like:

on-click: [
	all [
		pf: parent-face? face
		do-actor pf 'on-click arg
	]
]


the code above would pass the received event in ARG value to the 
ON-CLICK actor of the parent face.


The #1 option would offer probably simpler shortcut to propagate 
the event up like:

on-click: none

but we would need to allow write in the dialect something like:

view [
	hpanel [
		box red on-click [print "red box clicked"]
		box blue on-click none
	] on-click [print "panel clicked"]
]


in the code above the ON-CLICK actor of blue box face could be set 
to NONE to allow propagate the click event up so the ON-CLICK actor 
of hpanel is executed.
Henrik, I think propagating large number of events is solved easily 
using the #2 as this is some kind of special case imo. normally you 
don't need to propagate even't too much. That's why others doesn't 
like the #2 option much imo.
Henrik
9-Jun-2011
[7192x2]
ok, I think I got it a bit backwards, so maybe #3 is OK.
I don't like the idea in #1 that an outer ON-CLICK overwrites an 
inner ON-CLICK in case the inner ON-CLICK is very complex.
Cyphre
9-Jun-2011
[7194x4]
The #1 is IMO very simmilar to #4..it differs just by the form of 
the syntax:

#1 example:

view [
	hpanel [
		box red on-click [print "red box clicked"]
		box blue on-click none
	] on-click [print "panel clicked"]
]

#4 example:

view [
	hpanel [
		box red on-click [print "red box clicked"]
		box blue options: [propagate-actors: [on-click]]
	] on-click [print "panel clicked"]
]
Henrik, "in case the inner ON-CLICK is very complex" what you mean 
by this? The inner ON-CLICK just doesn't have to be defined, not 
complex if you want to execute the outer one no?
Otherwise in the #1 case I can image there could be some confusing 
situations where some face doesn't have some actor defined and the 
event will 'bubble' too much up in the face structure causing execution 
of unwanted actor. What do you think?
image=imagine
Rebolek
9-Jun-2011
[7198]
I think if such confusing situation will happen, it's solely style's 
writer responsibility.
Cyphre
9-Jun-2011
[7199]
So maybe th #3 is really best default behaviour that keeps events 
under control. I agree here that in case of #3, if you want to propagate 
event's then you would need to write more code that you would like 
though but  OTOH you know what you are doing.
Henrik
9-Jun-2011
[7200x2]
Cyphre, I was supposing that this would be the same for style content 
as well as for layouts. Hard to explain without a deeper study of 
all the mechanics of how events are propagated or overwritten.
For style content you would use standard styles that may have complex 
event handlers. You likely don't want to overwrite those.
Cyphre
9-Jun-2011
[7202]
Rebolek, that's not true. You can create layouts with misc actors 
combinations that will behave strange and you'll be scratching your 
head where to put at least empty actor to stop the unvantred propagation.
Pekr
9-Jun-2011
[7203x2]
As for overriding. I am not sure higher level on-click should disable 
lower level on-click. In the OOP I used (CA-Visual Objects), and 
just IIRC (so sorry, if inaccurate), you had such options:

- to execute child method

- in the above you either returned false (maybe I get this one wrong, 
but you get the idea) or the parent method was called right after 
the child's method 

- there was also some override option, but I don't remember it, it 
is 12 years old experience
Cyphre: if we go for #3, will there be the option to "insert-event-func" 
like in R2 ('detect functionality), which would allow us to apply 
some filters? E.g. for dev/demo purposes?