make widget stuff manglable
[catagits/Reaction.git] / lib / Reaction / UI / Widget / Container.pm
CommitLineData
1c41e332 1package Reaction::UI::Widget::Container;
2
3use Reaction::UI::WidgetClass;
4
5use aliased 'Reaction::UI::ViewPort';
6
7class Container which {
8
9 our $child_name;
10
11 # somewhat evil. fragment returns ($name, $code) to pass to implements
12 # or a method modifier name, so [1] will get us just the code
13
14 # This is convenient to do here but DO NOT duplicate this code outside of
15 # the same dist as WidgetClass since it's internals-dependent.
16
17 my $child_fragment_method
18 = (fragment container_child {
19 arg '_' => $_{viewport}->$child_name;
20 render 'viewport';
21 })[1];
22
23 around _method_for_fragment_name => sub {
24 my $orig = shift;
25 my $self = shift;
26 my ($fragment_name) = @_;
27 if (defined($child_name)
28 && $fragment_name eq $child_name) {
29 return $self->$orig(@_) || $child_fragment_method;
30 }
31 return $self->$orig(@_);
32 };
33
34 before _fragment_widget => sub {
35 my ($self, $do_render, $args, $new_args) = @_;
36 my @contained_names = $self->_contained_names($args->{viewport});
37 foreach my $name (@contained_names) {
38 $new_args->{$name} ||= sub {
39 local $child_name = $name;
40 $self->render($name, @_);
41 };
42 }
43 };
44
45 implements _contained_names => sub {
46 my ($self, $vp) = @_;
47 my @names;
48 foreach my $attr ($vp->meta->compute_all_applicable_attributes) {
49 next unless eval { $attr->type_constraint->name->isa(ViewPort) };
50 my $name = $attr->name;
51 next if ($name eq 'outer');
52 push(@names, $name);
53 }
54 return @names;
55 };
56
57};
58
591;