Commit | Line | Data |
ddccc6a2 |
1 | package Reaction::UI::ViewPort::Collection; |
2 | |
3 | use Reaction::Class; |
4 | use Scalar::Util qw/blessed/; |
5 | use aliased 'Reaction::InterfaceModel::Collection' => 'IM_Collection'; |
6 | use aliased 'Reaction::UI::ViewPort::Object'; |
7 | |
7b5e71ad |
8 | use MooseX::Types::Moose qw/Str HashRef/; |
9 | |
81393881 |
10 | use namespace::clean -except => [ qw(meta) ]; |
11 | extends 'Reaction::UI::ViewPort'; |
ddccc6a2 |
12 | |
81393881 |
13 | has members => (is => 'rw', isa => 'ArrayRef', lazy_build => 1); |
14 | |
15 | has collection => (is => 'ro', isa => IM_Collection, required => 1); |
16 | has current_collection => (is => 'rw', isa => IM_Collection, lazy_build => 1); |
17 | |
7b5e71ad |
18 | has member_args => ( is => 'rw', isa => HashRef, lazy_build => 1); |
19 | has member_class => ( is => 'ro', isa => Str, lazy_build => 1); |
f46fa4fd |
20 | |
81393881 |
21 | sub BUILD { |
22 | my ($self, $args) = @_; |
23 | if( my $member_args = delete $args->{Member} ){ |
24 | $self->member_args( $member_args ); |
25 | } |
f46fa4fd |
26 | } |
27 | |
28 | sub _build_member_args { {} } |
29 | |
81393881 |
30 | sub _build_member_class { Object }; |
31 | |
32 | after clear_current_collection => sub{ |
33 | shift->clear_members; #clear the members the current collection changes, duh |
ddccc6a2 |
34 | }; |
f46fa4fd |
35 | |
81393881 |
36 | sub _build_current_collection { |
37 | return $_[0]->collection; |
f46fa4fd |
38 | } |
81393881 |
39 | |
40 | #I'm not really sure why this is here all of a sudden. |
f46fa4fd |
41 | sub model { shift->current_collection } |
42 | |
81393881 |
43 | sub _build_members { |
44 | my ($self) = @_; |
45 | my (@members, $i); |
46 | my $args = $self->member_args; |
47 | my $builders = {}; |
f46fa4fd |
48 | my $field_orders = {}; |
81393881 |
49 | my $ctx = $self->ctx; |
50 | my $loc = join('-', $self->location, 'member'); |
51 | my $class = $self->member_class; |
52 | |
53 | #replace $i with a real unique identifier so that we don't run a risk of |
54 | # events being passed down to the wrong viewport. for now i disabled event |
55 | # passing until i fix this (groditi) |
56 | for my $obj ( $self->current_collection->members ) { |
57 | my $type = blessed $obj; |
58 | my $builder_cache = $builders->{$type} ||= {}; |
f46fa4fd |
59 | my @order; |
60 | if( exists $args->{computed_field_order} ){ |
61 | @order = (computed_field_order => $args->{computed_field_order}); |
62 | } elsif( exists $field_orders->{$type} ) { |
63 | @order = (computed_field_order => $field_orders->{$type}); |
64 | } |
65 | |
81393881 |
66 | my $member = $class->new( |
f46fa4fd |
67 | ctx => $ctx, |
68 | model => $obj, |
69 | location => join('-', $loc, $i++), |
70 | builder_cache => $builder_cache, |
71 | @order, %$args, |
72 | ); |
73 | |
74 | #cache to prevent the sort function from having to be run potentially |
75 | #hundreds of times |
76 | $field_orders->{$type} ||= $member->computed_field_order unless @order; |
81393881 |
77 | push(@members, $member); |
78 | } |
79 | return \@members; |
80 | }; |
81 | |
82 | __PACKAGE__->meta->make_immutable; |
83 | |
ddccc6a2 |
84 | |
2dba7201 |
85 | 1; |
ddccc6a2 |
86 | |
2dba7201 |
87 | __END__; |
ddccc6a2 |
88 | |
2dba7201 |
89 | =head1 NAME |
90 | |
91 | Reaction::UI::ViewPort::Collection |
92 | |
93 | =head1 DESCRIPTION |
94 | |
7460b544 |
95 | Creates, from an InterfaceModel::Collection, a list of viewports representing |
96 | each member of the collection. |
2dba7201 |
97 | |
98 | =head1 ATTRIBUTES |
99 | |
100 | =head2 collection |
101 | |
7460b544 |
102 | Required read-only L<InterfaceModel::Collection|Reaction::InterfaceModel::Collection> |
103 | This is the original collection. |
104 | |
2dba7201 |
105 | =head2 current_collection |
106 | |
7460b544 |
107 | Read-only, lazy-building |
108 | L<InterfaceModel::Collection|Reaction::InterfaceModel::Collection> |
109 | This is the collection that will be used to create C<members> and should be |
110 | altered to reflect any ordering, paging, etc. By default this is the |
111 | same thing as C<collection>. |
112 | |
2dba7201 |
113 | =head2 member_args |
114 | |
7460b544 |
115 | A read-write HASH ref of additional parameters to pass to the C<member_class> |
116 | constructor as items are instantiated. |
117 | |
2dba7201 |
118 | =head2 member_class |
119 | |
7460b544 |
120 | The class to use when instantiating items to represent the member items. |
121 | |
122 | See: L<Object|Reaction::UI::ViewPort::Object>, |
123 | L<Member|Reaction::UI::ViewPort::Grid::Member>, |
124 | L<Member::WithActions|Reaction::UI::ViewPort::Grid::Member::WithActions>, |
125 | |
2dba7201 |
126 | =head1 INTERNAL METHODS |
127 | |
7460b544 |
128 | These methods, although stable, are subject to change without notice. |
129 | Extend at your own risk, APIs may change in the future. |
2dba7201 |
130 | |
131 | =head2 BUILD |
132 | |
7460b544 |
133 | Intercept a parameter with the key C<Member> amd store it in C<member_args> |
2dba7201 |
134 | |
135 | =head2 model |
136 | |
7460b544 |
137 | Returns the C<current_collection> |
138 | |
139 | =head2 _build_members |
140 | |
141 | Build individual viewports for each member of the collection, |
142 | |
143 | =head2 _build_member_args |
144 | |
145 | Defaults to an empty HASH ref. |
146 | |
147 | =head2 _build_member_class |
148 | |
149 | Defaults to L<Reaction::UI::ViewPort::Object> |
150 | |
2dba7201 |
151 | =head1 AUTHORS |
152 | |
153 | See L<Reaction::Class> for authors. |
154 | |
155 | =head1 LICENSE |
156 | |
157 | See L<Reaction::Class> for the license. |
158 | |
159 | =cut |