r15425@deathmachine (orig r456): groditi | 2008-01-02 13:49:19 -0500
[catagits/Reaction.git] / lib / Reaction / UI / Window.pm
CommitLineData
7adfd53f 1package Reaction::UI::Window;
2
3use Reaction::Class;
4use Reaction::UI::FocusStack;
5
6class Window which {
7
8 has ctx => (isa => 'Catalyst', is => 'ro', required => 1);
9 has view_name => (isa => 'Str', is => 'ro', lazy_fail => 1);
10 has content_type => (isa => 'Str', is => 'ro', lazy_fail => 1);
11 has title => (isa => 'Str', is => 'rw', default => sub { 'Untitled window' });
12 has view => (
13 # XXX compile failure because the Catalyst::View constraint would be
14 # auto-generated which doesn't work with unions. ::Types::Catalyst needed.
15 #isa => 'Catalyst::View|Reaction::UI::View',
16 isa => 'Object', is => 'ro', lazy_build => 1
17 );
18 has focus_stack => (
19 isa => 'Reaction::UI::FocusStack',
20 is => 'ro', required => 1,
21 default => sub { Reaction::UI::FocusStack->new },
22 );
89939ff9 23
24 implements _build_view => as {
7adfd53f 25 my ($self) = @_;
26 return $self->ctx->view($self->view_name);
27 };
89939ff9 28
7adfd53f 29 implements flush => as {
30 my ($self) = @_;
31 $self->flush_events;
32 $self->flush_view;
33 };
89939ff9 34
7adfd53f 35 implements flush_events => as {
36 my ($self) = @_;
37 my $ctx = $self->ctx;
38 foreach my $type (qw/query body/) {
39 my $meth = "${type}_parameters";
40 my $param_hash = $ctx->req->$meth;
41 $self->focus_stack->apply_events($ctx, $param_hash);
42 }
43 };
89939ff9 44
7adfd53f 45 implements flush_view => as {
46 my ($self) = @_;
47 return if $self->ctx->res->status =~ /^3/ || length($self->ctx->res->body);
48 $self->ctx->res->body(
49 $self->view->render_window($self)
50 );
51 $self->ctx->res->content_type($self->content_type);
52 };
53
54 # required by old Renderer::XHTML
89939ff9 55
7adfd53f 56 implements render_viewport => as {
57 my ($self, $vp) = @_;
58 return unless $vp;
59 return $self->view->render_viewport($self, $vp);
60 };
61
62};
63
641;
65
66=head1 NAME
67
68Reaction::UI::Window - Container for rendering the UI elements in
69
70=head1 SYNOPSIS
71
72 my $window = Reaction::UI::Window->new(
73 ctx => $ctx,
74 view_name => $view_name,
75 content_type => $content_type,
76 title => $window_title,
77 );
78
9964b409 79 # More commonly, as Reaction::UI::Controller::Root creates one for you:
7adfd53f 80 my $window = $ctx->stash->{window};
81
89939ff9 82 # Resolve current events and render the view of the UI
7adfd53f 83 # elements of this Window:
9964b409 84 # This is called by the end action of Reaction::UI::Controller::Root
7adfd53f 85 $window->flush();
86
87 # Resolve current events:
88 $window->flush_events();
89
90 # Render the top ViewPort in the FocusStack of this Window:
91 $window->flush_view();
92
93 # Render a particular ViewPort:
94 $window->render_viewport($viewport);
95
96 # Or in a template:
97 [% window.render_viewport(self.inner) %]
98
99 # Add a ViewPort to the UI:
100 $window->focus_stack->push_viewport('Reaction::UI::ViewPort');
101
102=head1 DESCRIPTION
103
104A Window object is created and stored in the stash by
9964b409 105L<Reaction::UI::Controller::Root>, it is used to contain all the
7adfd53f 106elements (ViewPorts) that make up the UI. The Window is rendered in
9964b409 107the end action of the Root Controller to make up the page.
7adfd53f 108
109To add L<ViewPorts|Reaction::UI::ViewPort> to the stack, read the
110L<Reaction::UI::FocusStack> and L<Reaction::UI::ViewPort> documentation.
111
112Several Window attributes are set by
9964b409 113L<Reaction::UI::Controller::Root/begin> when a new Window is created,
7adfd53f 114these are as follows:
115
116=over
117
118=item ctx
119
120The current L<Catalyst> context object is set.
121
122=item view_name
123
9964b409 124The view_name is set from the L<Reaction::UI::Controller::Root> attributes.
7adfd53f 125
126=item content_type
127
9964b409 128The content_type is set from the L<Reaction::UI::Controller::Root> attributes.
7adfd53f 129
9964b409 130=item title
7adfd53f 131
9964b409 132The title is set from the L<Reaction::UI::Controller::Root>
133window_title attribute.
7adfd53f 134
135=back
136
137=head1 METHODS
138
139=head2 ctx
140
141=over
142
9964b409 143=item Arguments: $ctx?
7adfd53f 144
145=back
146
9964b409 147Retrieve/set the current L<Catalyst> context object.
7adfd53f 148
149=head2 view_name
150
151=over
152
9964b409 153=item Arguments: %viewname?
7adfd53f 154
155=back
156
9964b409 157Retrieve/set the name of the L<Catalyst::View> component used to render
7adfd53f 158this Window. If this has not been set, rendering the Window will fail.
159
160=head2 content_type
161
162=over
163
9964b409 164=item Arguments: $contenttype?
7adfd53f 165
166=back
167
168Retrieve the content_type for the page. If this has not been set,
169rendering the Window will fail.
170
171=head2 title
172
173=over
174
175=item Arguments: $title?
176
177=back
178
179 [% window.title %]
180
9964b409 181Retrieve/set the title of this page, if not set, it will default to
7adfd53f 182"Untitled window".
183
184=head2 view
185
186=over
187
188=item Arguments: none
189
190=back
191
192Retrieve the L<Catalyst::View> instance, this can be set, or will be
193instantiated using the L<view_name> class.
194
195=head2 focus_stack
196
197=over
198
199=item Arguments: none
200
201=back
202
203 $window->focus_stack->push_viewport('Reaction::UI::ViewPort');
204
205Retrieve the L<stack|Reaction::UI::FocusStack> of
206L<ViewPorts|Reaction::UI::ViewPorts> that contains all the UI elements
207for this Window. Use L<Reaction::UI::FocusStack/push_viewport> on this
208to create more elements. An empty FocusStack is created by the
9964b409 209Controller::Root when the Window is created.
7adfd53f 210
211=head2 render_viewport
212
213=over
214
215=item Arguments: $viewport
216
217=back
218
219 $window->render_viewport($viewport);
220
221 [% window.render_viewport(self.inner) %]
222
223Calls render on the L<view> object used by this Window. The following
224arguments are given:
225
226=over
227
228=item ctx
229
230The L<Catalyst> context object.
231
232=item self
233
234The ViewPort object to be rendered.
235
236=item window
237
238The Window object.
239
240=item type
241
242The string that describes the layout from L<Reaction::UI::ViewPort/layout>.
243
244=back
245
246=head2 flush
247
248=over
249
250=item Arguments: none
251
252=back
253
254Synchronize the current events with all the L<Reaction::UI::ViewPort>
255objects in the UI, then render the root ViewPort. This is called for
9964b409 256you by L<Reaction::UI::Controller::Root/end>.
7adfd53f 257
258=head2 flush_events
259
260=over
261
262=item Arguments: none
263
264=back
265
266Resolves all the current events, first the query parameters then the
267body parameters, with all the L<Reaction::UI::ViewPort> objects in the
268UI. This calls L<Reaction::UI::FocusStack/apply_events>. This method
269is called by L<flush>.
270
271=head2 flush_view
272
273=over
274
275=item Arguments: none
276
277=back
278
279Renders the page into the L<Catalyst::Response> body, unless the
280response status is already set to 3xx, or the body has already been
281filled. This calls L<render_viewport> with the root
282L<Reaction::UI::ViewPort> from the L<focus_stack>. This method is
283called by L<flush>.
284
285=head1 AUTHORS
286
287See L<Reaction::Class> for authors.
288
289=head1 LICENSE
290
291See L<Reaction::Class> for the license.
292
293=cut