more POD!
[catagits/Reaction.git] / lib / Reaction / UI / Window.pm
CommitLineData
7adfd53f 1package Reaction::UI::Window;
2
3use Reaction::Class;
4use Reaction::UI::FocusStack;
5
81393881 6use namespace::clean -except => [ qw(meta) ];
7
8
9has ctx => (isa => 'Catalyst', is => 'ro', required => 1);
10has view_name => (isa => 'Str', is => 'ro', lazy_fail => 1);
8b3b4820 11has content_type => (isa => 'Str', is => 'rw', lazy_fail => 1);
81393881 12has title => (isa => 'Str', is => 'rw', default => sub { 'Untitled window' });
13has view => (
14 # XXX compile failure because the Catalyst::View constraint would be
15 # auto-generated which doesn't work with unions. ::Types::Catalyst needed.
16 #isa => 'Catalyst::View|Reaction::UI::View',
17 isa => 'Object', is => 'ro', lazy_build => 1
18);
19has focus_stack => (
20 isa => 'Reaction::UI::FocusStack',
21 is => 'ro', required => 1,
22 default => sub { Reaction::UI::FocusStack->new },
23);
24sub _build_view {
25 my ($self) = @_;
26 return $self->ctx->view($self->view_name);
27};
28sub flush {
29 my ($self) = @_;
30 $self->flush_events;
31 $self->flush_view;
32};
33sub flush_events {
34 my ($self) = @_;
35 my $ctx = $self->ctx;
36
37 #I really think we should make a copies of the parameter hashes here
38 #and then as we handle events, delete ethem from the event hashref, so
39 #that it thins down as it makes it down the viewport tree. which would
40 #limit the number of events that get to the children viewports. it wont
41 #save that many subcalls unless there is a lot of child_items, but it's
42 #more about doing the correct thing. It also avoids children viewports
43 #being able to see their parents' events, which leaves the door open for
44 #abuse of the system. thoughts anyone?
45
46 foreach my $type (qw/query body/) {
47 my $meth = "${type}_parameters";
48 my $param_hash = $ctx->req->$meth;
52f292b2 49 $self->focus_stack->apply_events($param_hash)
81393881 50 if keys %$param_hash;
51 }
52};
53sub flush_view {
54 my ($self) = @_;
55 my $res = $self->ctx->res;
56 if ( $res->status =~ /^3/ || length($res->body) ) {
57 $res->content_type('text/plain') unless $res->content_type;
58 return;
59 }
60 $res->body($self->view->render_window($self));
61 $res->content_type($self->content_type);
62};
7adfd53f 63
81393881 64# required by old Renderer::XHTML
65sub render_viewport {
66 my ($self, $vp) = @_;
67 return unless $vp;
68 return $self->view->render_viewport($self, $vp);
7adfd53f 69};
70
81393881 71__PACKAGE__->meta->make_immutable;
72
73
7adfd53f 741;
75
76=head1 NAME
77
78Reaction::UI::Window - Container for rendering the UI elements in
79
80=head1 SYNOPSIS
81
82 my $window = Reaction::UI::Window->new(
83 ctx => $ctx,
84 view_name => $view_name,
85 content_type => $content_type,
86 title => $window_title,
87 );
88
9964b409 89 # More commonly, as Reaction::UI::Controller::Root creates one for you:
7adfd53f 90 my $window = $ctx->stash->{window};
91
89939ff9 92 # Resolve current events and render the view of the UI
7adfd53f 93 # elements of this Window:
9964b409 94 # This is called by the end action of Reaction::UI::Controller::Root
7adfd53f 95 $window->flush();
96
97 # Resolve current events:
98 $window->flush_events();
99
100 # Render the top ViewPort in the FocusStack of this Window:
101 $window->flush_view();
102
103 # Render a particular ViewPort:
104 $window->render_viewport($viewport);
105
106 # Or in a template:
107 [% window.render_viewport(self.inner) %]
108
109 # Add a ViewPort to the UI:
110 $window->focus_stack->push_viewport('Reaction::UI::ViewPort');
111
112=head1 DESCRIPTION
113
114A Window object is created and stored in the stash by
9964b409 115L<Reaction::UI::Controller::Root>, it is used to contain all the
7adfd53f 116elements (ViewPorts) that make up the UI. The Window is rendered in
9964b409 117the end action of the Root Controller to make up the page.
7adfd53f 118
f1cd5548 119To add L<ViewPorts|Reaction::UI::ViewPort> to the stack, use the
120L<Reaction::UI::Controller/push_viewport> method. For more detailed
121information, read the L<Reaction::UI::FocusStack> and
122L<Reaction::UI::ViewPort> documentation.
7adfd53f 123
f1cd5548 124=head1 ATTRIBUTES
7adfd53f 125
f1cd5548 126These are set for you by L<Reaction::UI::Controller::Root/begin> from
127your Root controller configuration.
7adfd53f 128
129=head2 ctx
130
131=over
132
9964b409 133=item Arguments: $ctx?
7adfd53f 134
135=back
136
f1cd5548 137The current L<Catalyst> context object.
7adfd53f 138
139=head2 view_name
140
141=over
142
f1cd5548 143=item Arguments: $viewname?
7adfd53f 144
145=back
146
9964b409 147Retrieve/set the name of the L<Catalyst::View> component used to render
7adfd53f 148this Window. If this has not been set, rendering the Window will fail.
149
150=head2 content_type
151
152=over
153
9964b409 154=item Arguments: $contenttype?
7adfd53f 155
156=back
157
158Retrieve the content_type for the page. If this has not been set,
159rendering the Window will fail.
160
161=head2 title
162
163=over
164
165=item Arguments: $title?
166
167=back
168
169 [% window.title %]
170
9964b409 171Retrieve/set the title of this page, if not set, it will default to
7adfd53f 172"Untitled window".
173
174=head2 view
175
176=over
177
178=item Arguments: none
179
180=back
181
182Retrieve the L<Catalyst::View> instance, this can be set, or will be
183instantiated using the L<view_name> class.
184
185=head2 focus_stack
186
187=over
188
189=item Arguments: none
190
191=back
192
193 $window->focus_stack->push_viewport('Reaction::UI::ViewPort');
194
195Retrieve the L<stack|Reaction::UI::FocusStack> of
196L<ViewPorts|Reaction::UI::ViewPorts> that contains all the UI elements
197for this Window. Use L<Reaction::UI::FocusStack/push_viewport> on this
198to create more elements. An empty FocusStack is created by the
9964b409 199Controller::Root when the Window is created.
7adfd53f 200
f1cd5548 201=head1 METHODS
7adfd53f 202
203=head2 flush
204
205=over
206
207=item Arguments: none
208
209=back
210
211Synchronize the current events with all the L<Reaction::UI::ViewPort>
212objects in the UI, then render the root ViewPort. This is called for
9964b409 213you by L<Reaction::UI::Controller::Root/end>.
7adfd53f 214
215=head2 flush_events
216
217=over
218
219=item Arguments: none
220
221=back
222
223Resolves all the current events, first the query parameters then the
224body parameters, with all the L<Reaction::UI::ViewPort> objects in the
225UI. This calls L<Reaction::UI::FocusStack/apply_events>. This method
226is called by L<flush>.
227
228=head2 flush_view
229
230=over
231
232=item Arguments: none
233
234=back
235
236Renders the page into the L<Catalyst::Response> body, unless the
237response status is already set to 3xx, or the body has already been
f1cd5548 238filled. This is done via L<Reaction::UI::View/render_window>. This
239method is called by L<flush>.
7adfd53f 240
241=head1 AUTHORS
242
243See L<Reaction::Class> for authors.
244
245=head1 LICENSE
246
247See L<Reaction::Class> for the license.
248
249=cut