API  0.9.6
 All Classes Files Functions Variables Macros Groups Pages
CPViewController.j
Go to the documentation of this file.
1 /*
2  * CPViewController.j
3  * AppKit
4  *
5  * Created by Nicholas Small and Francisco Tolmasky.
6  * Copyright 2009, 280 North, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 
24 
25 
27 
61 @implementation CPViewController : CPResponder
62 {
63  CPView _view;
64  BOOL _isLoading;
65  BOOL _isLazy;
66  BOOL _isViewLoaded;
67 
68  id _representedObject;
69  CPString _title;
70 
71  CPString _cibName;
72  CPBundle _cibBundle;
73  CPDictionary _cibExternalNameTable;
74 }
75 
76 + (void)initialize
77 {
78  if (self !== [CPViewController class])
79  return;
80 
82 }
83 
87 - (id)init
88 {
89  return [self initWithCibName:nil bundle:nil];
90 }
91 
92 - (id)initWithCibName:(CPString)aCibNameOrNil bundle:(CPBundle)aCibBundleOrNil
93 {
94  return [self initWithCibName:aCibNameOrNil bundle:aCibBundleOrNil externalNameTable:nil];
95 }
96 
97 - (id)initWithCibName:(CPString)aCibNameOrNil bundle:(CPBundle)aCibBundleOrNil owner:(id)anOwner
98 {
99  return [self initWithCibName:aCibNameOrNil bundle:aCibBundleOrNil externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]];
100 }
101 
115 - (id)initWithCibName:(CPString)aCibNameOrNil bundle:(CPBundle)aCibBundleOrNil externalNameTable:(CPDictionary)anExternalNameTable
116 {
117  self = [super init];
118 
119  if (self)
120  {
121  // Don't load the cib until someone actually requests the view. The user may just be intending to use setView:.
122  _cibName = aCibNameOrNil;
123  _cibBundle = aCibBundleOrNil || [CPBundle mainBundle];
124  _cibExternalNameTable = anExternalNameTable || [CPDictionary dictionaryWithObject:self forKey:CPCibOwner];
125 
126  _isLoading = NO;
127  _isLazy = NO;
128  }
129 
130  return self;
131 }
132 
149 - (void)loadView
150 {
151  if (_view)
152  return;
153 
154  if (_cibName)
155  {
156  // check if a cib is already cached for the current _cibName
157  var cib = [CPViewControllerCachedCibs objectForKey:_cibName];
158 
159  if (!cib)
160  {
161  // if the cib isn't cached yet : fetch it and cache it
162  cib = [[CPCib alloc] initWithCibNamed:_cibName bundle:_cibBundle];
163  [CPViewControllerCachedCibs setObject:cib forKey:_cibName];
164  }
165 
166  [cib instantiateCibWithExternalNameTable:_cibExternalNameTable];
167  }
168  else
169  _view = [CPView new];
170 }
171 
179 - (CPView)view
180 {
181  if (!_view)
182  {
183  _isLoading = YES;
184 
185  var cibOwner = [_cibExternalNameTable objectForKey:CPCibOwner];
186 
187  if ([cibOwner respondsToSelector:@selector(viewControllerWillLoadCib:)])
188  [cibOwner viewControllerWillLoadCib:self];
189 
190  [self loadView];
191 
192  if (_view === nil && [cibOwner isKindOfClass:[CPDocument class]])
193  [self setView:[cibOwner valueForKey:@"view"]];
194 
195  if (!_view)
196  {
197  var reason = [CPString stringWithFormat:@"View for %@ could not be loaded from Cib or no view specified. Override loadView to load the view manually.", self];
198 
199  [CPException raise:CPInternalInconsistencyException reason:reason];
200  }
201 
202  if ([cibOwner respondsToSelector:@selector(viewControllerDidLoadCib:)])
203  [cibOwner viewControllerDidLoadCib:self];
204 
205  _isLoading = NO;
206  [self _viewDidLoad];
207  }
208  else if (_isLazy)
209  {
210  _isLazy = NO;
211  [self _viewDidLoad];
212  }
213 
214  return _view;
215 }
216 
217 - (void)_viewDidLoad
218 {
219  [self willChangeValueForKey:"isViewLoaded"];
220  [self viewDidLoad];
221  isViewLoaded = YES;
222  [self didChangeValueForKey:"isViewLoaded"];
223 }
224 
233 - (void)viewDidLoad
234 {
235 
236 }
237 
238 
247 - (void)setView:(CPView)aView
248 {
249  var willChangeIsViewLoaded = (_isViewLoaded == NO && aView != nil) || (_isViewLoaded == YES && aView == nil);
250 
251  if (willChangeIsViewLoaded)
252  [self willChangeValueForKey:"isViewLoaded"];
253 
254  _view = aView;
255  _isViewLoaded = aView !== nil;
256 
257  if (willChangeIsViewLoaded)
258  [self didChangeValueForKey:"isViewLoaded"];
259 }
260 
261 - (BOOL)automaticallyNotifiesObserversOfIsViewLoaded
262 {
263  return NO;
264 }
265 
266 @end
267 
268 
269 var CPViewControllerViewKey = @"CPViewControllerViewKey",
270  CPViewControllerTitleKey = @"CPViewControllerTitleKey",
271  CPViewControllerCibNameKey = @"CPViewControllerCibNameKey",
272  CPViewControllerBundleKey = @"CPViewControllerBundleKey";
273 
275 
281 - (id)initWithCoder:(CPCoder)aCoder
282 {
283  self = [super initWithCoder:aCoder];
284 
285  if (self)
286  {
287  _view = [aCoder decodeObjectForKey:CPViewControllerViewKey];
288  _title = [aCoder decodeObjectForKey:CPViewControllerTitleKey];
289  _cibName = [aCoder decodeObjectForKey:CPViewControllerCibNameKey];
290 
291  var bundlePath = [aCoder decodeObjectForKey:CPViewControllerBundleKey];
292  _cibBundle = bundlePath ? [CPBundle bundleWithPath:bundlePath] : [CPBundle mainBundle];
293 
294  _cibExternalNameTable = [CPDictionary dictionaryWithObject:self forKey:CPCibOwner];
295  _isLazy = YES;
296  }
297 
298  return self;
299 }
300 
305 - (void)encodeWithCoder:(CPCoder)aCoder
306 {
307  [super encodeWithCoder:aCoder];
308 
309  [aCoder encodeObject:_view forKey:CPViewControllerViewKey];
310  [aCoder encodeObject:_title forKey:CPViewControllerTitleKey];
311  [aCoder encodeObject:_cibName forKey:CPViewControllerCibNameKey];
312  [aCoder encodeObject:[_cibBundle bundlePath] forKey:CPViewControllerBundleKey];
313 }
314 
315 @end
316 
318 
322 - (CPView)view
323 {
324  return _view;
325 }
326 
330 - (void)setView:(CPView)aValue
331 {
332  _view = aValue;
333 }
334 
338 - (BOOL)isViewLoaded
339 {
340  return _isViewLoaded;
341 }
342 
346 - (id)representedObject
347 {
348  return _representedObject;
349 }
350 
354 - (void)setRepresentedObject:(id)aValue
355 {
356  _representedObject = aValue;
357 }
358 
362 - (CPString)title
363 {
364  return _title;
365 }
366 
370 - (void)setTitle:(CPString)aValue
371 {
372  _title = aValue;
373 }
374 
378 - (CPString)cibName
379 {
380  return _cibName;
381 }
382 
386 - (CPBundle)cibBundle
387 {
388  return _cibBundle;
389 }
390 
394 - (CPDictionary)cibExternalNameTable
395 {
396  return _cibExternalNameTable;
397 }
398 
399 @end