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

Reply via email to