ObjectivelyMVC 0.1.0
Object oriented MVC framework for OpenGL, SDL2 and GNU C
Checkbox.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 "Checkbox.h"
27
28#include "check.png.h"
29
30#define _Class _Checkbox
31
32static Image *_check;
33
34#pragma mark - Object
35
39static void dealloc(Object *self) {
40
41 Checkbox *this = (Checkbox *) self;
42
43 release(this->box);
44 release(this->check);
45
46 super(Object, self, dealloc);
47}
48
49#pragma mark - View
50
54static void awakeWithDictionary(View *self, const Dictionary *dictionary) {
55
56 super(View, self, awakeWithDictionary, dictionary);
57
58 Checkbox *this = (Checkbox *) self;
59
60 const Inlet inlets[] = MakeInlets(
61 MakeInlet("check", InletTypeView, &this->check, NULL)
62 );
63
64 $(self, bind, inlets, dictionary);
65}
66
70static View *init(View *self) {
71 return (View *) $((Checkbox *) self, initWithFrame, NULL);
72}
73
74#pragma mark - Control
75
79static _Bool captureEvent(Control *self, const SDL_Event *event) {
80
81 const View *box = (View *) ((Checkbox *) self)->box;
82
83 if (event->type == SDL_MOUSEBUTTONDOWN) {
84 if ($(box, didReceiveEvent, event)) {
86 return true;
87 }
88 }
89 if (event->type == SDL_MOUSEBUTTONUP) {
90 if ($(box, didReceiveEvent, event)) {
92 self->state &= ~ControlStateHighlighted;
93 return true;
94 }
95 }
96
97 return super(Control, self, captureEvent, event);
98}
99
103static void stateDidChange(Control *self) {
104
105 super(Control, self, stateDidChange);
106
107 Checkbox *this = (Checkbox *) self;
108
109 if (self->state & ControlStateSelected) {
110 this->check->view.hidden = false;
111 } else {
112 this->check->view.hidden = true;
113 }
114}
115
116#pragma mark - Checkbox
117
122static Checkbox *initWithFrame(Checkbox *self, const SDL_Rect *frame) {
123
124 self = (Checkbox *) super(Control, self, initWithFrame, frame);
125 if (self) {
126
128
129 self->box = $(alloc(Control), initWithFrame, frame);
130 assert(self->box);
131
133
134 self->check = $(alloc(ImageView), initWithImage, _check);
135 assert(self->check);
136
138 self->check->view.hidden = true;
139
140 $((View *) self->box, addSubview, (View *) self->check);
141 $((View *) self, addSubview, (View *) self->box);
142 }
143
144 return self;
145}
146
147#pragma mark - Class lifecycle
148
152static void initialize(Class *clazz) {
153
154 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
155
156 ((ViewInterface *) clazz->interface)->awakeWithDictionary = awakeWithDictionary;
157 ((ViewInterface *) clazz->interface)->init = init;
158
159 ((ControlInterface *) clazz->interface)->captureEvent = captureEvent;
160 ((ControlInterface *) clazz->interface)->stateDidChange = stateDidChange;
161
162 ((CheckboxInterface *) clazz->interface)->initWithFrame = initWithFrame;
163
164 _check = $(alloc(Image), initWithBytes, check_png, check_png_len);
165}
166
170static void destroy(Class *clazz) {
171 release(_check);
172}
173
178Class *_Checkbox(void) {
179 static Class *clazz;
180 static Once once;
181
182 do_once(&once, {
183 clazz = _initialize(&(const ClassDef) {
184 .name = "Checkbox",
185 .superclass = _Control(),
186 .instanceSize = sizeof(Checkbox),
187 .interfaceOffset = offsetof(Checkbox, interface),
188 .interfaceSize = sizeof(CheckboxInterface),
190 .destroy = destroy,
191 });
192 });
193
194 return clazz;
195}
196
197#undef _Class
static void destroy(Class *clazz)
Definition: Checkbox.c:170
static void dealloc(Object *self)
Definition: Checkbox.c:39
static Image * _check
Definition: Checkbox.c:32
static void initialize(Class *clazz)
Definition: Checkbox.c:152
Checkboxes are toggle Controls that respond to click events.
@ ControlStateHighlighted
Definition: Control.h:68
@ ControlStateSelected
Definition: Control.h:70
@ InletTypeView
Definition: View+JSON.h:139
#define MakeInlets(...)
Creates a null-termianted array of Inlets.
Definition: View+JSON.h:221
#define MakeInlet(name, type, dest, data)
Creates an Inlet with the specified parameters.
Definition: View+JSON.h:216
@ ViewAutoresizingFill
Definition: View.h:89
@ ViewAutoresizingContain
Definition: View.h:91
@ ViewAlignmentMiddleCenter
Definition: View.h:72
Box * initWithFrame(Box *self, const SDL_Rect *frame)
Initializes this Box with the given frame.
Definition: Box.c:92
Button * initWithImage(Button *self, Image *image)
Initializes this Button with the sopecified Image.
Definition: Button.c:122
Checkboxes are toggle Controls that respond to click events.
Definition: Checkbox.h:43
ImageView * check
The check.
Definition: Checkbox.h:64
Control * box
The box.
Definition: Checkbox.h:59
Control control
The superclass.
Definition: Checkbox.h:48
Class * _Checkbox(void)
The Checkbox archetype.
Definition: Checkbox.c:178
CollectionView * init(CollectionView *self, const SDL_Rect *frame)
Initializes this CollectionView with the specified frame and style.
Controls are Views which capture events and dispatch Actions.
Definition: Control.h:83
void stateDidChange(Control *self)
Called when the state of this Control changes.
Definition: Checkbox.c:103
_Bool captureEvent(Control *self, const SDL_Event *event)
Captures a given event, potentially altering the state of this Control.
Definition: Button.c:76
Class * _Control(void)
The Control archetype.
Definition: Control.c:379
unsigned int state
The bit mask of ControlState.
Definition: Control.h:110
View view
The superclass.
Definition: Control.h:88
Image loading.
Definition: Image.h:38
Image * initWithBytes(Image *self, const uint8_t *bytes, size_t length)
Initializes this Image with the specified bytes.
Definition: Image.c:88
ImageViews render an Image in the context of a View hierarchy.
Definition: ImageView.h:43
View view
The superclass.
Definition: ImageView.h:48
Inlets enable inbound data binding of View attributes through JSON.
Definition: View+JSON.h:155
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
Definition: View.h:133
_Bool bind(View *self, const Inlet *inlets, const Dictionary *dictionary)
Performs data binding for the Inlets described in dictionary.
ViewAlignment alignment
The alignment.
Definition: View.h:149
_Bool hidden
If true, this View is not drawn.
Definition: View.h:195
void addSubview(View *self, View *subview)
Adds a subview to this view, to be drawn above its siblings.
Definition: PageView.c:35
_Bool didReceiveEvent(const View *self, const SDL_Event *event)
Definition: View.c:546
int autoresizingMask
The ViewAutoresizing bitmask.
Definition: View.h:154
void awakeWithDictionary(View *self, const Dictionary *dictionary)
Wakes this View with the specified Dictionary.
Definition: Box.c:50