r18493@agaton (orig r702): wreis | 2008-05-02 22:28:12 +0100
[catagits/Reaction.git] / lib / Reaction / UI / ViewPort.pm
index 4c5ac5a..02a1390 100644 (file)
@@ -1,11 +1,15 @@
 package Reaction::UI::ViewPort;
 
 use Reaction::Class;
+use Scalar::Util qw/blessed/;
 
 class ViewPort which {
 
+  sub DEBUG_EVENTS () { $ENV{REACTION_UI_VIEWPORT_DEBUG_EVENTS} }
+
   has location => (isa => 'Str', is => 'rw', required => 1);
   has layout => (isa => 'Str', is => 'rw', lazy_build => 1);
+  has layout_args => (isa => 'HashRef', is => 'ro', default => sub { {} });
   has outer => (isa => 'Reaction::UI::ViewPort', is => 'rw', weak_ref => 1);
   has inner => (isa => 'Reaction::UI::ViewPort', is => 'rw');
   has focus_stack => (
@@ -14,13 +18,12 @@ class ViewPort which {
   has _tangent_stacks => (
     isa => 'HashRef', is => 'ro', default => sub { {} }
   );
-  has ctx => (isa => 'Catalyst', is => 'ro', required => 1);
-  has column_order => (is => 'rw');
-  
-  implements build_layout => as {
+  has ctx => (isa => 'Catalyst', is => 'ro'); #, required => 1);
+
+  implements _build_layout => as {
     '';
   };
-  
+
   implements create_tangent => as {
     my ($self, $name) = @_;
     my $t_map = $self->_tangent_stacks;
@@ -32,7 +35,7 @@ class ViewPort which {
     $t_map->{$name} = $tangent;
     return $tangent;
   };
-  
+
   implements focus_tangent => as {
     my ($self, $name) = @_;
     if (my $tangent = $self->_tangent_stacks->{$name}) {
@@ -41,31 +44,37 @@ class ViewPort which {
       return;
     }
   };
-  
+
   implements focus_tangents => as {
     return keys %{shift->_tangent_stacks};
   };
-  
+
   implements child_event_sinks => as {
     my $self = shift;
     return values %{$self->_tangent_stacks};
   };
-  
+
   implements apply_events => as {
     my ($self, $ctx, $events) = @_;
+    return unless keys %$events;
     $self->apply_child_events($ctx, $events);
     $self->apply_our_events($ctx, $events);
   };
-  
+
   implements apply_child_events => as {
     my ($self, $ctx, $events) = @_;
+    return unless keys %$events;
     foreach my $child ($self->child_event_sinks) {
+      confess blessed($child) ."($child) is not a valid object"
+        unless blessed($child) && $child->can('apply_events');
       $child->apply_events($ctx, $events);
     }
   };
-  
+
   implements apply_our_events => as {
     my ($self, $ctx, $events) = @_;
+    my @keys = keys %$events;
+    return unless @keys;
     my $loc = $self->location;
     my %our_events;
     foreach my $key (keys %$events) {
@@ -78,27 +87,42 @@ class ViewPort which {
       $self->handle_events(\%our_events);
     }
   };
-  
+
   implements handle_events => as {
     my ($self, $events) = @_;
+    my $exists = exists $events->{exists};
+    if ($exists) {
+      my %force = $self->force_events;
+      my @need = grep { !exists $events->{$_} } keys %force;
+      @{$events}{@need} = @force{@need};
+    }
     foreach my $event ($self->accept_events) {
       if (exists $events->{$event}) {
+        if (DEBUG_EVENTS) {
+          my $name = join(' at ', $self, $self->location);
+          $self->ctx->log->debug(
+            "Applying Event: $event on $name with value: "
+            .(defined $events->{$event} ? $events->{$event} : '<undef>')
+          );
+        }
         $self->$event($events->{$event});
       }
     }
   };
-  
+
   implements accept_events => as { () };
-  
+
+  implements force_events => as { () };
+
   implements event_id_for => as {
     my ($self, $name) = @_;
     return join(':', $self->location, $name);
   };
-  
+
   implements sort_by_spec => as {
     my ($self, $spec, $items) = @_;
     return $items if not defined $spec;
-  
+
     my @order;
     if (ref $spec eq 'ARRAY') {
       @order = @$spec;
@@ -107,12 +131,12 @@ class ViewPort which {
       return $items unless length $spec;
       @order = split /\s+/, $spec;
     }
-  
+
     my %order_map = map {$_ => 0} @$items;
     for my $order_num (0..$#order) {
       $order_map{ $order[$order_num] } = ($#order - $order_num) + 1;
     }
-  
+
     return [sort {$order_map{$b} <=> $order_map{$a}} @$items];
   };
 
@@ -156,7 +180,7 @@ Reaction::UI::ViewPort - Page layout building block
   # Resolve current events with this ViewPort
   $vp->apply_events($ctx, $param_hash);
 
-  # Apply current events to all tangent stacks 
+  # Apply current events to all tangent stacks
   # This is called by apply_events
   $vp->apply_child_events($ctx, $params_hash);
 
@@ -233,7 +257,7 @@ ViewPorts classname.
 
 This is generally used by more specialised ViewPorts such as the
 L<ListView|Reaction::UI::ViewPort::ListView> or
-L<ActionForm|Reaction::UI::ViewPort::ActionForm>. It can be either a
+L<Action|Reaction::UI::ViewPort::Action>. It can be either a
 space separated list of column names, or an arrayref of column names.
 
 =back
@@ -374,7 +398,7 @@ returns the location and the name, joined with a colon.
 
 Sorts the given list of items such that the ones that also appear in
 the spec are at the beginning. This is called by
-L<Reaction::UI::ViewPort::ActionForm> and
+L<Reaction::UI::ViewPort::Action> and
 L<Reaction::UI::ViewPort::ListView>, and gets passed L<column_order>
 as the spec argument.