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