On Sat, 2004-03-13 at 11:01, Rocco Caputo wrote: > On Sat, Mar 13, 2004 at 03:35:47AM -0800, Scott Beck wrote: > > Hola, > > > > Currently I am working on a Perl client class for Y Windows > > (http://www.y-windows.org). My Y class currently acts like a > > POE::Component in that it creates it's own session and passes events > > back to the calling session. I am looking for a way to propagate events > > up to different widgets if the event is not handled in the widget it was > > for. Right now I am using this hack: > > [hack] > > In the widget libraries I've worked with, some master Application > class handles outside events and dispatches them to appropriate > widgets. They find the appropriate keystroke target by walking down > a focus chain, from screen (always focused) -> window (whichever is on > top) -> widget (which one has the cursor). Mouse clicks reach their > destination by a simple form of ray casting: The Z order chain is > walked front to back (top to bottom?) until the click point intersects > with something. >
Finding the focused widget in Y Windows is done by the server. I currently get events for a specific widget ID. > I think these sorts of specialized event dispatch systems are best > implemented outside POE. Applications can become very large if every > button, checkbox, text string, panel, and box is a separate session. > Response time will be displeasing if keystrokes and mouse clicks must > propagate through a queue several times. I don't think I explained this very well. Y.pm creates a single session. Each widget registers with the Y session when it is created and requests certain events. When an event comes in, the Y session dispatches to the focused widget (passed in from the server) the event. Each widget keeps a hash of registered events to sessions that registered them. So I have: sub connect_signal { my $self = shift; my $signal_name = shift; my $event = shift; my $session = $poe_kernel->get_active_session; push @{$self->{registered}{$signal_name}}, [ $session->ID, $event, @_ ]; } in a base class for widgets. So a typical App will look like this: use Y; use Y::Window; use Y::Label; use POE; POE::Session->create( inline_states => { _start => sub { Y->initialize('connected') }, close => sub { $_[KERNEL]->post(Y => "shutdown") }, connected => sub { my $window = new Y::Window; $window->set_property(title => "Test Window"); my $label = new Y::Label; $label->set_property(text => "Hello, World!"); $window->set_child($label); $window->connect_signal(requestClose => 'close'); $window->show; $_[HEAP]{window} = $window; }, } ); # Calles $poe_kernel->run Y->run; What I want to be able to do is find a nicer way to propagate the events up the widget hierarchy. As it stands, I keep a doubly linked tree within the widget structures. Each widget knows it's parent and it's children. When an event comes to a widget I want to somehow be able to know if the session I posted the event to handled it and if it did not, continue up the widget hierarchy until a session says it handled the event or until I reach the top of the tree (the main window). Scott -- Scott Beck <[EMAIL PROTECTED]> Gossamer Threads