ObjectivelyMVC 0.1.0
Object oriented MVC framework for OpenGL, SDL2 and GNU C
ViewController.c
Go to the documentation of this file.
1/*
2 * ObjectivelyMVC: Object oriented MVC framework for OpenGL, SDL2 and GNU C.
3 * Copyright (C) 2014 Jay Dolan <jay@jaydolan.com>
4 *
5 * This software is provided 'as-is', without any express or implied
6 * warranty. In no event will the authors be held liable for any damages
7 * arising from the use of this software.
8 *
9 * Permission is granted to anyone to use this software for any purpose,
10 * including commercial applications, and to alter it and redistribute it
11 * freely, subject to the following restrictions:
12 *
13 * 1. The origin of this software must not be misrepresented; you must not
14 * claim that you wrote the original software. If you use this software
15 * in a product, an acknowledgment in the product documentation would be
16 * appreciated but is not required.
17 *
18 * 2. Altered source versions must be plainly marked as such, and must not be
19 * misrepresented as being the original software.
20 *
21 * 3. This notice may not be removed or altered from any source distribution.
22 */
23
24#include <assert.h>
25
26#include "ViewController.h"
27
28#define _Class _ViewController
29
30#pragma mark - Object
31
35static void dealloc(Object *self) {
36
37 ViewController *this = (ViewController *) self;
38
39 release(this->childViewControllers);
40 release(this->view);
41
42 super(Object, self, dealloc);
43}
44
45#pragma mark - ViewController
46
51static void addChildViewController(ViewController *self, ViewController *childViewController) {
52
53 assert(childViewController);
54
55 ViewController *that = retain(childViewController);
56
57 $(childViewController, removeFromParentViewController);
58
59 $(self->childViewControllers, addObject, childViewController);
60 childViewController->parentViewController = self;
61
62 $(self, loadViewIfNeeded);
63 $(childViewController, loadViewIfNeeded);
64
65 if (self->view->window) {
66 $(childViewController, viewWillAppear);
67 }
68
69 $(self->view, addSubview, childViewController->view);
70 $(childViewController->view, updateBindings);
71
72 if (self->view->window) {
73 $(childViewController, viewDidAppear);
74 }
75
76 release(that);
77}
78
82static void handleNotification_recurse(const Array *array, ident obj, ident data) {
83 $((ViewController *) obj, handleNotification, data);
84}
85
90static void handleNotification(ViewController *self, const Notification *notification) {
91 $((Array *) self->childViewControllers, enumerateObjects, handleNotification_recurse, (ident) notification);
92}
93
99
100 self = (ViewController *) super(Object, self, init);
101 if (self) {
102 self->childViewControllers = $$(MutableArray, arrayWithCapacity, 0);
103 assert(self->childViewControllers);
104 }
105
106 return self;
107}
108
113static void loadView(ViewController *self) {
114
115 View *view = $(alloc(View), initWithFrame, NULL);
116 assert(view);
117
119
120 $(self, setView, view);
121 release(view);
122}
123
129
130 if (self->view == NULL) {
131 $(self, loadView);
132 }
133
134 assert(self->view);
135}
136
141static void moveToParentViewController(ViewController *self, ViewController *parentViewController) {
142
143 ViewController *this = retain(self);
144
146
147 if (parentViewController) {
148 $(parentViewController, addChildViewController, self);
149 }
150
151 release(this);
152}
153
158static void removeChildViewController(ViewController *self, ViewController *childViewController) {
159
160 assert(childViewController);
161 assert(childViewController->parentViewController == self);
162
163 ViewController *that = retain(childViewController);
164
165 $(self->childViewControllers, removeObject, childViewController);
166 childViewController->parentViewController = NULL;
167
168 $(childViewController, viewWillDisappear);
169 $(childViewController->view, removeFromSuperview);
170 $(childViewController, viewDidDisappear);
171
172 release(that);
173}
174
180
181 if (self->parentViewController) {
183 }
184}
185
190static void respondToEvent(ViewController *self, const SDL_Event *event) {
191
192}
193
198static void setView(ViewController *self, View *view) {
199
200 if (view != self->view) {
201
202 if (self->view) {
203 self->view->viewController = NULL;
204 release(self->view);
205 }
206
207 if (view) {
208 self->view = retain(view);
209 self->view->viewController = self;
210 } else {
211 self->view = NULL;
212 }
213 }
214}
215
219static void viewDidAppear_recurse(const Array *array, ident obj, ident data) {
220 $((ViewController *) obj, viewDidAppear);
221}
222
227static void viewDidAppear(ViewController *self) {
228 $((Array *) self->childViewControllers, enumerateObjects, viewDidAppear_recurse, NULL);
229}
230
234static void viewDidDisappear_recurse(const Array *array, ident obj, ident data) {
235 $((ViewController *) obj, viewDidAppear);
236}
237
243 $((Array *) self->childViewControllers, enumerateObjects, viewDidDisappear_recurse, NULL);
244}
245
249static void viewWillAppear_recurse(const Array *array, ident obj, ident data) {
250 $((ViewController *) obj, viewWillAppear);
251}
252
257static void viewWillAppear(ViewController *self) {
258 $((Array *) self->childViewControllers, enumerateObjects, viewWillAppear_recurse, NULL);
259}
260
264static void viewWillDisappear_recurse(const Array *array, ident obj, ident data) {
266}
267
273 $((Array *) self->childViewControllers, enumerateObjects, viewWillDisappear_recurse, NULL);
274}
275
276#pragma mark - Class lifecycle
277
281static void initialize(Class *clazz) {
282
283 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
284
285 ((ViewControllerInterface *) clazz->interface)->addChildViewController = addChildViewController;
286 ((ViewControllerInterface *) clazz->interface)->handleNotification = handleNotification;
287 ((ViewControllerInterface *) clazz->interface)->init = init;
288 ((ViewControllerInterface *) clazz->interface)->loadView = loadView;
289 ((ViewControllerInterface *) clazz->interface)->loadViewIfNeeded = loadViewIfNeeded;
290 ((ViewControllerInterface *) clazz->interface)->moveToParentViewController = moveToParentViewController;
291 ((ViewControllerInterface *) clazz->interface)->removeChildViewController = removeChildViewController;
292 ((ViewControllerInterface *) clazz->interface)->removeFromParentViewController = removeFromParentViewController;
293 ((ViewControllerInterface *) clazz->interface)->respondToEvent = respondToEvent;
294 ((ViewControllerInterface *) clazz->interface)->setView = setView;
295 ((ViewControllerInterface *) clazz->interface)->viewDidAppear = viewDidAppear;
296 ((ViewControllerInterface *) clazz->interface)->viewDidDisappear = viewDidDisappear;
297 ((ViewControllerInterface *) clazz->interface)->viewWillAppear = viewWillAppear;
298 ((ViewControllerInterface *) clazz->interface)->viewWillDisappear = viewWillDisappear;
299}
300
305Class *_ViewController(void) {
306 static Class *clazz;
307 static Once once;
308
309 do_once(&once, {
310 clazz = _initialize(&(const ClassDef) {
311 .name = "ViewController",
312 .superclass = _Object(),
313 .instanceSize = sizeof(ViewController),
314 .interfaceOffset = offsetof(ViewController, interface),
315 .interfaceSize = sizeof(ViewControllerInterface),
317 });
318 });
319
320 return clazz;
321}
322
323#undef _Class
@ ViewAutoresizingFill
Definition: View.h:89
static void handleNotification_recurse(const Array *array, ident obj, ident data)
ArrayEnumerator for handleNotification recursion.
static void viewWillDisappear_recurse(const Array *array, ident obj, ident data)
ArrayEnumerator for viewWillDisappear recursion.
static void viewDidDisappear_recurse(const Array *array, ident obj, ident data)
ArrayEnumerator for viewDidDisappear recursion.
static void dealloc(Object *self)
static void viewWillAppear_recurse(const Array *array, ident obj, ident data)
ArrayEnumerator for viewWillAppear recursion.
static void initialize(Class *clazz)
static void viewDidAppear_recurse(const Array *array, ident obj, ident data)
ArrayEnumerator for viewDidAppear recursion.
A ViewController manages a View and its descendants.
Box * initWithFrame(Box *self, const SDL_Rect *frame)
Initializes this Box with the given frame.
Definition: Box.c:92
CollectionView * init(CollectionView *self, const SDL_Rect *frame)
Initializes this CollectionView with the specified frame and style.
The Notification type.
Definition: Notification.h:34
A ViewController manages a View and its descendants.
View * view
The main view.
Class * _ViewController(void)
The ViewController archetype.
void loadView(ViewController *self)
Loads this ViewController's View.
void removeFromParentViewController(ViewController *self)
Removes this ViewController from its parent.
void setView(ViewController *self, View *view)
Sets this ViewController's View.
void addChildViewController(ViewController *self, ViewController *childViewController)
Adds the specified child ViewController to this ViewController.
void loadViewIfNeeded(ViewController *self)
Loads this ViewController's View if it is not already loaded.
ViewController * parentViewController
The parent view controller.
void viewWillAppear(ViewController *self)
This method is invoked before this ViewController's View is added to the View hierarchy.
void moveToParentViewController(ViewController *self, ViewController *parentViewController)
Moves this ViewController to the specified parent.
MutableArray * childViewControllers
The child view controllers.
void viewDidDisappear(ViewController *self)
This method is invoked after this ViewController's View is removed to the View hierarchy.
void viewWillDisappear(ViewController *self)
This method is invoked before this ViewController's View is removed from the View hierarchy.
void handleNotification(ViewController *self, const Notification *notification)
Handles a broadcast notification.
void removeChildViewController(ViewController *self, ViewController *childViewController)
Removes the specified child ViewController from this ViewController.
void viewDidAppear(ViewController *self)
This method is invoked after this ViewController's View is added to the View hierarchy.
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
Definition: View.h:133
void updateBindings(View *self)
Updates data bindings, prompting the appropriate layout changes.
ViewController * viewController
The ViewController.
Definition: View.h:264
SDL_Window * window
The window.
Definition: View.h:276
void addSubview(View *self, View *subview)
Adds a subview to this view, to be drawn above its siblings.
Definition: PageView.c:35
int autoresizingMask
The ViewAutoresizing bitmask.
Definition: View.h:154
void removeFromSuperview(View *self)
Removes this View from its superview.
Definition: View.c:1175
void respondToEvent(View *self, const SDL_Event *event)
Responds to the specified event.
Definition: Control.c:213