merging in the lats of my two branches and killing them off
[catagits/Reaction.git] / lib / Reaction / UI / ViewPort / GridView.pm
CommitLineData
e22de101 1package Reaction::UI::ViewPort::GridView;
2
3use Reaction::Class;
4
e716714f 5use aliased 'Reaction::InterfaceModel::Collection' => 'IM_Collection';
b8faba69 6use aliased 'Reaction::UI::ViewPort::GridView::Entity';
e22de101 7
8class GridView is 'Reaction::UI::ViewPort', which {
9
b8faba69 10 has exclude_fields => ( isa => 'ArrayRef', is => 'ro' );
11 has field_order => ( isa => 'ArrayRef', is => 'ro', lazy_build => 1);
12 has field_labels => ( isa => 'HashRef', is => 'ro', lazy_build => 1);
13
14
15 has entities => ( isa => 'ArrayRef', is => 'rw', lazy_build => 1);
e22de101 16
e716714f 17 has collection => (isa => IM_Collection, is => 'ro', required => 1);
18 has current_collection => (isa => IM_Collection, is => 'rw', lazy_build => 1);
e22de101 19
b8faba69 20 has entity_class => ( isa => 'Str', is => 'rw', lazy_build => 1);
21 has entity_args => ( is => 'rw' );
22
23 implements BUILD => as {
24 my ($self, $args) = @_;
25 my $entity_args = delete $args->{Entity};
26 $self->entity_args( $entity_args ) if ref $entity_args;
27 };
28
29 after clear_current_collection => sub{
30 shift->clear_entities; #clear the entitiesis the current collection changes, duh
31 };
e22de101 32
89939ff9 33 implements _build_entity_class => as { Entity };
b8faba69 34
89939ff9 35 implements _build_field_order => as {
e22de101 36 my ($self) = @_;
37 my %excluded = map { $_ => undef }
b8faba69 38 @{ $self->has_exclude_fields ? $self->exclude_fields : [] };
e22de101 39 #XXX this abuse of '_im_class' needs to be fixed ASAP
40 my $object_class = $self->collection->_im_class;
e716714f 41 my @fields = $object_class->meta->parameter_attributes;
42 #obviously only get fields with readers.
43 @fields = grep { $_->get_read_method } @fields;
e22de101 44 #eliminate excluded fields & treat names that start with an underscore as private
45 @fields = grep {$_->name !~ /^_/ && !exists $excluded{$_->name} } @fields;
e716714f 46
e22de101 47 #eliminate fields marked as collections, or fields that are arrayrefs
48 @fields = grep {
49 !($_->has_type_constraint &&
50 ($_->type_constraint->is_a_type_of('ArrayRef') ||
51 eval {$_->type_constraint->name->isa('Reaction::InterfaceModel::Collection')} ||
52 eval { $_->_isa_metadata->isa('Reaction::InterfaceModel::Collection') }
53 )
54 ) } @fields;
55
56 #order the columns all nice and pretty, and only get fields with readers, duh
e716714f 57 my $ordered = $self->sort_by_spec
58 ( $self->column_order, [ map { (($_->name) || ()) } @fields] );
59
60 return $ordered;
e22de101 61 };
62
89939ff9 63 implements _build_current_collection => as {
e22de101 64 shift->collection;
65 };
66
89939ff9 67 implements _build_field_labels => as {
e716714f 68 my $self = shift;
b8faba69 69 my %labels;
70 for my $field ( @{$self->field_order}){
71 $labels{$field} = join(' ', map{ ucfirst } split('_', $field));
e716714f 72 }
b8faba69 73 return \%labels;
e716714f 74 };
75
89939ff9 76 implements _build_entities => as {
b8faba69 77 my ($self) = @_;
78 my (@entities, $i);
79 my $args = $self->has_entity_args ? $self->entity_args : {};
80 my $builders = {};
81 my $ctx = $self->ctx;
82 my $loc = $self->location;
83 my $order = $self->field_order;
84 my $class = $self->entity_class;
85 for my $obj ( $self->current_collection->members ) {
86 my $row = $class->new(
87 ctx => $ctx,
88 object => $obj,
89 location => join('-', $loc, 'row', $i++),
90 field_order => $order,
91 builder_cache => $builders,
92 ref $args ? %$args : ()
93 );
94 push(@entities, $row);
e716714f 95 }
b8faba69 96 return \@entities;
e716714f 97 };
98
e22de101 99};
100
101
102
1031;