ObjectivelyMVC 0.1.0
Object oriented MVC framework for OpenGL, SDL2 and GNU C
ImageView.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 "ImageView.h"
27
28const EnumName GLBlendNames[] = MakeEnumNames(
29 MakeEnumName(GL_CONSTANT_ALPHA),
30 MakeEnumName(GL_CONSTANT_COLOR),
31 MakeEnumName(GL_DST_ALPHA),
32 MakeEnumName(GL_DST_COLOR),
33 MakeEnumName(GL_ONE),
34 MakeEnumName(GL_ONE_MINUS_DST_ALPHA),
35 MakeEnumName(GL_ONE_MINUS_DST_COLOR),
36 MakeEnumName(GL_ONE_MINUS_SRC_ALPHA),
37 MakeEnumName(GL_ONE_MINUS_SRC_COLOR),
38 MakeEnumName(GL_SRC_ALPHA),
39 MakeEnumName(GL_SRC_COLOR),
40 MakeEnumName(GL_ZERO)
41);
42
43#define _Class _ImageView
44
45#pragma mark - Object
46
50static void dealloc(Object *self) {
51
52 ImageView *this = (ImageView *) self;
53
54 release(this->image);
55
56 if (this->texture) {
57 glDeleteTextures(1, &this->texture);
58 }
59
60 super(Object, self, dealloc);
61}
62
63#pragma mark - View
64
68static void awakeWithDictionary(View *self, const Dictionary *dictionary) {
69
70 super(View, self, awakeWithDictionary, dictionary);
71
72 ImageView *this = (ImageView *) self;
73
74 const Inlet inlets[] = MakeInlets(
75 MakeInlet("blend.src", InletTypeEnum, &this->blend.src, (ident) GLBlendNames),
76 MakeInlet("blend.dst", InletTypeEnum, &this->blend.dst, (ident) GLBlendNames),
77 MakeInlet("color", InletTypeColor, &this->color, NULL),
78 MakeInlet("image", InletTypeImage, &this->image, NULL)
79 );
80
81 $(self, bind, inlets, dictionary);
82}
83
87static View *init(View *self) {
88 return (View *) $((ImageView *) self, initWithImage, NULL);
89}
90
94static void render(View *self, Renderer *renderer) {
95
96 super(View, self, render, renderer);
97
98 ImageView *this = (ImageView *) self;
99
100 if (this->texture == 0) {
101 if (this->image) {
102 this->texture = $(renderer, createTexture, this->image->surface);
103 assert(this->texture);
104 }
105 }
106
107 if (this->texture) {
108
109 // TODO: Actually use self->blend
110
111 $(renderer, setDrawColor, &this->color);
112 const SDL_Rect frame = $(self, renderFrame);
113 $(renderer, drawTexture, this->texture, &frame);
114 $(renderer, setDrawColor, &Colors.White);
115 }
116}
117
121static void renderDeviceWillReset(View *self) {
122
123 ImageView *this = (ImageView *) self;
124
125 if (this->texture) {
126 glDeleteTextures(1, &this->texture);
127 }
128
129 this->texture = 0;
130
131 super(View, self, renderDeviceWillReset);
132}
133
134#pragma mark - ImageView
135
140static ImageView *initWithFrame(ImageView *self, const SDL_Rect *frame) {
141
142 self = (ImageView *) super(View, self, initWithFrame, frame);
143 if (self) {
144 self->blend.src = GL_SRC_ALPHA;
145 self->blend.dst = GL_ONE_MINUS_SRC_ALPHA;
146
147 self->color = Colors.White;
148 }
149
150 return self;
151}
152
157static ImageView *initWithImage(ImageView *self, Image *image) {
158
159 self = (ImageView *) $(self, initWithFrame, NULL);
160 if (self) {
161 $(self, setImage, image);
162 }
163
164 return self;
165}
166
171static void setImage(ImageView *self, Image *image) {
172
173 release(self->image);
174
175 if (image) {
176 self->image = retain(image);
177
178 const SDL_Size size = $((View *) self, size);
179 const SDL_Size imageSize = $(image, size);
180
181 if (size.w == 0 && size.h == 0) {
182 $((View *) self, resize, &imageSize);
183 }
184 } else {
185 self->image = NULL;
186 }
187
188 self->texture = 0;
189}
190
195static void setImageWithResource(ImageView *self, const Resource *resource) {
196
197 Image *image = $$(Image, imageWithResource, resource);
198
199 $(self, setImage, image);
200
201 release(image);
202}
203
208static void setImageWithResourceName(ImageView *self, const char *name) {
209
210 Resource *resource = $$(Resource, resourceWithName, name);
211
212 $(self, setImageWithResource, resource);
213
214 release(resource);
215}
216
221static void setImageWithSurface(ImageView *self, SDL_Surface *surface) {
222
223 $(self, setImage, NULL);
224
225 if (surface) {
226 Image *image = $(alloc(Image), initWithSurface, surface);
227 assert(image);
228
229 $(self, setImage, image);
230
231 release(image);
232 }
233}
234
235#pragma mark - Class lifecycle
236
240static void initialize(Class *clazz) {
241
242 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
243
244 ((ViewInterface *) clazz->interface)->awakeWithDictionary = awakeWithDictionary;
245 ((ViewInterface *) clazz->interface)->init = init;
246 ((ViewInterface *) clazz->interface)->render = render;
247 ((ViewInterface *) clazz->interface)->renderDeviceWillReset = renderDeviceWillReset;
248
249 ((ImageViewInterface *) clazz->interface)->initWithFrame = initWithFrame;
250 ((ImageViewInterface *) clazz->interface)->initWithImage = initWithImage;
251 ((ImageViewInterface *) clazz->interface)->setImage = setImage;
252 ((ImageViewInterface *) clazz->interface)->setImageWithResource = setImageWithResource;
253 ((ImageViewInterface *) clazz->interface)->setImageWithResourceName = setImageWithResourceName;
254 ((ImageViewInterface *) clazz->interface)->setImageWithSurface = setImageWithSurface;
255}
256
261Class *_ImageView(void) {
262 static Class *clazz;
263 static Once once;
264
265 do_once(&once, {
266 clazz = _initialize(&(const ClassDef) {
267 .name = "ImageView",
268 .superclass = _View(),
269 .instanceSize = sizeof(ImageView),
270 .interfaceOffset = offsetof(ImageView, interface),
271 .interfaceSize = sizeof(ImageViewInterface),
273 });
274 });
275
276 return clazz;
277}
278
279#undef _Class
const EnumName GLBlendNames[]
Definition: ImageView.c:28
static void dealloc(Object *self)
Definition: ImageView.c:50
static void initialize(Class *clazz)
Definition: ImageView.c:240
ImageViews render an Image in the context of a View hierarchy.
@ InletTypeImage
Definition: View+JSON.h:90
@ InletTypeEnum
Definition: View+JSON.h:75
@ InletTypeColor
Definition: View+JSON.h:62
#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
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
CollectionView * init(CollectionView *self, const SDL_Rect *frame)
Initializes this CollectionView with the specified frame and style.
W3C Color constants.
Definition: Colors.h:37
SDL_Color White
Definition: Colors.h:185
Image loading.
Definition: Image.h:38
SDL_Size size(const Image *self)
Definition: Image.c:181
Image * initWithSurface(Image *self, SDL_Surface *surface)
Initializes this Image with the given surface.
Definition: Image.c:157
Image * imageWithResource(const Resource *resource)
Instantiates an Image with the specified Resource.
Definition: Image.c:64
ImageViews render an Image in the context of a View hierarchy.
Definition: ImageView.h:43
GLenum dst
Definition: ImageView.h:60
Image * image
The image.
Definition: ImageView.h:71
void setImageWithResource(ImageView *self, const Resource *resource)
Sets the Image for this ImageView with the given Resource.
Definition: ImageView.c:195
GLenum src
Definition: ImageView.h:60
void setImage(ImageView *self, Image *image)
Sets the Image for this ImageView.
Definition: ImageView.c:171
void setImageWithSurface(ImageView *self, SDL_Surface *surface)
A convenience method to set this view's Image with a surface.
Definition: ImageView.c:221
GLuint texture
The texture.
Definition: ImageView.h:76
Class * _ImageView(void)
Definition: ImageView.c:261
void setImageWithResourceName(ImageView *self, const char *name)
Sets the Image for this ImageView with the Resource by the given name.
Definition: ImageView.c:208
SDL_Color color
The drawing color.
Definition: ImageView.h:66
struct ImageView::@0 blend
The blend function.
Inlets enable inbound data binding of View attributes through JSON.
Definition: View+JSON.h:155
The Renderer is responsible for rasterizing the View hierarchy of a WindowController.
Definition: Renderer.h:50
GLuint createTexture(const Renderer *self, const SDL_Surface *surface)
Generates and binds to an OpenGL texture object, uploading the given surface.
Definition: Renderer.c:56
void renderDeviceWillReset(Renderer *self)
This method is invoked when the render device will become reset.
Definition: Renderer.c:252
void drawTexture(const Renderer *self, GLuint texture, const SDL_Rect *dest)
Draws a textured GL_QUAD in the given rectangle.
Definition: Renderer.c:155
void setDrawColor(Renderer *self, const SDL_Color *color)
Sets the primary color for drawing operations.
Definition: Renderer.c:281
The SDL_Size type.
Definition: Types.h:62
int w
Definition: Types.h:63
int h
Definition: Types.h:63
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.
Class * _View(void)
The View archetype.
Definition: View.c:1769
void resize(View *self, const SDL_Size *size)
Resizes this View to the specified size.
Definition: View.c:1326
void awakeWithDictionary(View *self, const Dictionary *dictionary)
Wakes this View with the specified Dictionary.
Definition: Box.c:50
SDL_Rect renderFrame(const View *self)
Definition: View.c:1275
void render(View *self, Renderer *renderer)
Renders this View using the given renderer.
Definition: Control.c:131