X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FReaction%2FUI%2FFocusStack.pm;h=0af90a827e57245596583034d079ccfab1766148;hb=e653a48785a1942da650254c8fba30706ca18333;hp=b786636dc8d0d819993d18eb7ccac1195c191213;hpb=db430ae8eb228482cbee8cc3c8a04c3aac30d606;p=catagits%2FReaction.git diff --git a/lib/Reaction/UI/FocusStack.pm b/lib/Reaction/UI/FocusStack.pm index b786636..0af90a8 100644 --- a/lib/Reaction/UI/FocusStack.pm +++ b/lib/Reaction/UI/FocusStack.pm @@ -2,78 +2,84 @@ package Reaction::UI::FocusStack; use Reaction::Class; -class FocusStack which { - - has vp_head => ( - isa => 'Reaction::UI::ViewPort', is => 'rw', - clearer => 'clear_vp_head', - ); - has vp_tail => ( - isa => 'Reaction::UI::ViewPort', is => 'rw', - clearer => 'clear_vp_tail', - ); - has vp_count => ( - isa => 'Int', is => 'rw', required => 1, default => sub { 0 } - ); - has loc_prefix => (isa => 'Str', is => 'rw', predicate => 'has_loc_prefix'); - - implements push_viewport => as { - my ($self, $class, %create) = @_; - my $tail = $self->vp_tail; - my $loc = $self->vp_count; - if ($self->has_loc_prefix) { - $loc = join('.', $self->loc_prefix, $loc); - } - my $vp = $class->new( - %create, - location => $loc, - focus_stack => $self, - (defined $tail ? ( outer => $tail ) : ()), # XXX possibly a bug in - #immutable? - ); - if ($tail) { # if we already have a tail (non-empty vp stack) - $tail->inner($vp); # set the current tail's inner vp to the new vp - } else { # else we're currently an empty stack - $self->vp_head($vp); # so set the head to the new vp - } - $self->vp_count($self->vp_count + 1); - $self->vp_tail($vp); - return $vp; - }; - - implements pop_viewport => as { - my ($self) = @_; - my $head = $self->vp_head; - confess "Can't pop from empty focus stack" unless defined($head); - my $vp = $self->vp_tail; - if ($vp eq $head) { - $self->clear_vp_head; - $self->clear_vp_tail; - } else { - $self->vp_tail($vp->outer); - } - $self->vp_count($self->vp_count - 1); - return $vp; - }; - - implements pop_viewports_to => as { - my ($self, $vp) = @_; - 1 while ($self->pop_viewport ne $vp); - return $vp; - }; - - implements apply_events => as { - my $self = shift; - my $vp = $self->vp_tail; - while (defined $vp) { - $vp->apply_events(@_); - $vp = $vp->outer; - } - }; - +use namespace::clean -except => [ qw(meta) ]; + + +has vp_head => ( + isa => 'Reaction::UI::ViewPort', is => 'rw', + clearer => 'clear_vp_head', +); +has vp_tail => ( + isa => 'Reaction::UI::ViewPort', is => 'rw', + clearer => 'clear_vp_tail', +); +has vp_count => ( + isa => 'Int', is => 'rw', required => 1, default => sub { 0 } +); +has loc_prefix => (isa => 'Str', is => 'rw', predicate => 'has_loc_prefix'); +sub push_viewport { + my ($self, $class, %create) = @_; + my $tail = $self->vp_tail; + my $loc = $self->vp_count; + if ($self->has_loc_prefix) { + $loc = join('-', $self->loc_prefix, $loc); + } + my $vp = $class->new( + %create, + location => $loc, + focus_stack => $self, + (defined $tail ? ( outer => $tail ) : ()), # XXX possibly a bug in + #immutable? + ); + if ($tail) { # if we already have a tail (non-empty vp stack) + $tail->inner($vp); # set the current tail's inner vp to the new vp + } else { # else we're currently an empty stack + $self->vp_head($vp); # so set the head to the new vp + } + $self->vp_count($self->vp_count + 1); + $self->vp_tail($vp); + return $vp; +}; + +sub pop_viewport { + my ($self) = @_; + my $head = $self->vp_head; + confess "Can't pop from empty focus stack" unless defined($head); + my $vp = $self->vp_tail; + if ($vp eq $head) { + $self->clear_vp_head; + $self->clear_vp_tail; + } else { + $self->vp_tail($vp->outer); + } + $self->vp_count($self->vp_count - 1); + return $vp; +}; + +sub pop_viewports_to { + my ($self, $vp) = @_; + 1 while ($self->pop_viewport ne $vp); + return $vp; +}; +sub apply_events { + my $self = shift; + my $all_events = shift; + my $vp = $self->vp_tail; + + while (defined $vp && keys %$all_events) { + my $loc = $vp->location; + my %vp_events = map { $_ => delete $all_events->{$_} } + grep { /^${loc}[-:]/ } keys %$all_events; + $vp->apply_events(\%vp_events); + $vp = $vp->outer; + } }; + +__PACKAGE__->meta->make_immutable; + + 1; =head1 NAME