X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FReaction%2FUI%2FView.pm;h=358fcf12251bc238805c72594a186549c6034182;hb=d9a3266fb7015bb1211171c1c113df3b1b7cd700;hp=4778c25ba1546f4321754a31595128931a399807;hpb=5a1a893ef93c22e0aba72a346749753ace194d66;p=catagits%2FReaction.git diff --git a/lib/Reaction/UI/View.pm b/lib/Reaction/UI/View.pm index 4778c25..358fcf1 100644 --- a/lib/Reaction/UI/View.pm +++ b/lib/Reaction/UI/View.pm @@ -3,89 +3,103 @@ package Reaction::UI::View; use Reaction::Class; # declaring dependencies - use Reaction::UI::LayoutSet; use Reaction::UI::RenderingContext; +use aliased 'Reaction::UI::Skin'; +use aliased 'Path::Class::Dir'; class View which { + has '_widget_cache' => (is => 'ro', default => sub { {} }); + has '_layout_set_cache' => (is => 'ro', default => sub { {} }); has 'app' => (is => 'ro', required => 1); has 'skin_name' => (is => 'ro', required => 1); + has 'skin' => ( + is => 'ro', lazy_build => 1, + handles => [ qw(create_layout_set search_path_for_type) ] + ); + has 'layout_set_class' => (is => 'ro', lazy_build => 1); has 'rendering_context_class' => (is => 'ro', lazy_build => 1); + implements '_build_layout_set_class' => as { + my ($self) = @_; + return $self->find_related_class('LayoutSet'); + }; + + implements '_build_rendering_context_class' => as { + my ($self) = @_; + return $self->find_related_class('RenderingContext'); + }; + + implements '_build_skin' => as { + my ($self) = @_; + Skin->new( + name => $self->skin_name, view => $self, + # path_to returns a File, not a Dir. Thanks, Catalyst. + skin_base_dir => Dir->new($self->app->path_to('share', 'skin')), + ); + }; + implements 'COMPONENT' => as { my ($class, $app, $args) = @_; return $class->new(%{$args||{}}, app => $app); }; - sub BUILD{ - my $self = shift; - my $skin_name = $self->skin_name; - my $skin_path = $self->app->path_to('share','skin',$skin_name); - confess("'${skin_path}' is not a valid path for skin '${skin_name}'") - unless -d $skin_path; - } - implements 'render_window' => as { my ($self, $window) = @_; my $root_vp = $window->focus_stack->vp_head; - $self->render_viewport(undef, $root_vp); + my $rctx = $self->create_rendering_context; + my ($widget, $args) = $self->render_viewport_args($root_vp); + $widget->render(widget => $rctx, $args); }; - implements 'render_viewport' => as { - my ($self, $outer_rctx, $vp) = @_; + implements 'render_viewport_args' => as { + my ($self, $vp) = @_; my $layout_set = $self->layout_set_for($vp); - my $rctx = $self->create_rendering_context( - layouts => $layout_set, - outer => $outer_rctx, - ); my $widget = $self->widget_for($vp, $layout_set); - $widget->render($rctx); + return ($widget, { viewport => $vp }); }; implements 'widget_for' => as { my ($self, $vp, $layout_set) = @_; - return $self->widget_class_for($layout_set) - ->new(view => $self, viewport => $vp); - }; - - implements 'widget_class_for' => as { - my ($self, $layout_set) = @_; - my $base = $self->blessed; - my $tail = $layout_set->widget_type; - my $class = join('::', $base, 'Widget', $tail); - Class::MOP::load_class($class); - return $class; + return + $self->_widget_cache->{$layout_set->name} + ||= $layout_set->widget_class + ->new( + view => $self, layout_set => $layout_set + ); }; implements 'layout_set_for' => as { my ($self, $vp) = @_; + #print STDERR "Getting layoutset for VP ".(ref($vp) || "SC:".$vp)."\n"; my $lset_name = eval { $vp->layout }; confess "Couldn't call layout method on \$vp arg ${vp}: $@" if $@; unless (length($lset_name)) { - my $last = (split('::',ref($vp)))[-1]; - $lset_name = join('_', map { lc($_) } split(/(?=[A-Z])/, $last)); + my $vp_class = ref($vp) || $vp; + my ($last) = ($vp_class =~ /.*(?:::ViewPort::)(.+?)$/); + my @fragments = split('::', $last); + $_ = join("_", split(/(?=[A-Z])/, $_)) for @fragments; + $lset_name = lc(join('/', @fragments)); + #print STDERR "--- $vp_class is rendered as $lset_name\n"; } my $cache = $self->_layout_set_cache; return $cache->{$lset_name} ||= $self->create_layout_set($lset_name); }; - implements 'create_layout_set' => as { - my ($self, $name) = @_; - return $self->layout_set_class->new( - $self->layout_set_args_for($name), - ); + implements 'layout_set_file_extension' => as { + confess View." is abstract, you must subclass it"; }; implements 'find_related_class' => as { my ($self, $rel) = @_; - my $own_class = ref($self)||$self; + my $own_class = ref($self) || $self; confess View." is abstract, you must subclass it" if $own_class eq View; foreach my $super ($own_class->meta->class_precedence_list) { next if $super eq View; @@ -99,26 +113,6 @@ class View which { confess "Unable to find related ${rel} class for ${own_class}"; }; - implements 'build_layout_set_class' => as { - my ($self) = @_; - return $self->find_related_class('LayoutSet'); - }; - - implements 'layout_set_args_for' => as { - my ($self, $name) = @_; - return (name => $name, search_path => $self->layout_search_path); - }; - - implements 'layout_search_path' => as { - my ($self) = @_; - return $self->search_path_for_type('layout'); - }; - - implements 'search_path_for_type' => as { - my ($self, $type) = @_; - return [ $self->app->path_to('share','skin',$self->skin_name,$type) ]; - }; - implements 'create_rendering_context' => as { my ($self, @args) = @_; return $self->rendering_context_class->new( @@ -127,12 +121,11 @@ class View which { ); }; - implements 'build_rendering_context_class' => as { - my ($self) = @_; - return $self->find_related_class('RenderingContext'); + implements 'rendering_context_args_for' => as { + return (); }; - implements 'rendering_context_args_for' => as { + implements 'layout_set_args_for' => as { return (); };