ObjectivelyMVC
Object oriented MVC framework for SDL3 and GNU C
Loading...
Searching...
No Matches
SlideShowView.c
Go to the documentation of this file.
1/*
2 * ObjectivelyMVC: Object oriented MVC framework for SDL3 and 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 <SDL3/SDL_timer.h>
27
28#include "SlideShowView.h"
29
30#define _Class _SlideShowView
31
32#pragma mark - Object
33
37static void dealloc(Object *self) {
38
39 SlideShowView *this = (SlideShowView *) self;
40
41 release(this->images);
42
43 super(Object, self, dealloc);
44}
45
46#pragma mark - View
47
51static View *init(View *self) {
52 return (View *) $((SlideShowView *) self, initWithFrame, NULL);
53}
54
58static void render(View *self, Renderer *renderer) {
59
60 super(View, self, render, renderer);
61
62 SlideShowView *this = (SlideShowView *) self;
63
64 const Array *images = (Array *) this->images;
65 if (images->count == 0) {
66 return;
67 }
68
69 const Uint64 now = SDL_GetTicks();
70
71 if (this->current->image == NULL) {
72 Image *first = $(images, firstObject);
73 $(this->current, setImage, first);
74 this->fadeEndedAt = now;
75 return;
76 }
77
78 if (images->count < 2) {
79 return;
80 }
81
82 if (this->fadeStartedAt) {
83 const float frac = (float) (now - this->fadeStartedAt) / (float) this->fadeDuration;
84 this->next->color.a = (Uint8) (SDL_min(frac, 1.f) * 255.f);
85 if (frac >= 1.f) {
86 $(this->current, setImage, this->next->image);
87 $(this->next, setImage, NULL);
88 this->next->color.a = 0;
89 this->fadeStartedAt = 0;
90 this->fadeEndedAt = now;
91 }
92 } else if (now - this->fadeEndedAt >= this->slideDuration) {
93 this->index = (this->index + 1) % images->count;
94 Image *image = $(images, objectAtIndex, this->index);
95 $(this->next, setImage, image);
96 this->fadeStartedAt = now;
97 }
98}
99
100#pragma mark - SlideShowView
101
106static void addImage(SlideShowView *self, Image *image) {
107
108 assert(image);
109
110 $(self->images, addObject, image);
111}
112
117static SlideShowView *initWithFrame(SlideShowView *self, const SDL_Rect *frame) {
118
119 self = (SlideShowView *) super(View, self, initWithFrame, frame);
120 if (self) {
121 self->images = $(alloc(Array), init);
122 assert(self->images);
123
124 self->slideDuration = 5000;
125 self->fadeDuration = 1000;
126
127 self->current = $(alloc(ImageView), initWithFrame, NULL);
128 assert(self->current);
129 $((View *) self, addSubview, (View *) self->current);
130 release(self->current);
131
132 self->next = $(alloc(ImageView), initWithFrame, NULL);
133 assert(self->next);
134 self->next->color.a = 0;
135 $((View *) self, addSubview, (View *) self->next);
136 release(self->next);
137 }
138
139 return self;
140}
141
142#pragma mark - Class lifecycle
143
147static void initialize(Class *clazz) {
148
149 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
150
151 ((ViewInterface *) clazz->interface)->render = render;
152 ((ViewInterface *) clazz->interface)->init = init;
153
154 ((SlideShowViewInterface *) clazz->interface)->addImage = addImage;
155 ((SlideShowViewInterface *) clazz->interface)->initWithFrame = initWithFrame;
156}
157
162Class *_SlideShowView(void) {
163 static Class *clazz;
164 static Once once;
165
166 do_once(&once, {
167 clazz = _initialize(&(const ClassDef) {
168 .name = "SlideShowView",
169 .superclass = _View(),
170 .instanceSize = sizeof(SlideShowView),
171 .interfaceOffset = offsetof(SlideShowView, interface),
172 .interfaceSize = sizeof(SlideShowViewInterface),
174 });
175 });
176
177 return clazz;
178}
179
180#undef _Class
static void setImage(ImageView *self, Image *image)
Definition ImageView.c:165
static void addSubview(View *self, View *subview)
Definition PageView.c:49
static SlideShowView * initWithFrame(SlideShowView *self, const SDL_Rect *frame)
static void addImage(SlideShowView *self, Image *image)
static View * init(View *self)
static void render(View *self, Renderer *renderer)
static void dealloc(Object *self)
Class * _SlideShowView(void)
static void initialize(Class *clazz)
SlideShowView cycles through a collection of Images with crossfade transitions.
Class * _View(void)
Definition View.c:2067
Image loading.
Definition Image.h:38
ImageViews render an Image in the context of a View hierarchy.
Definition ImageView.h:45
Renderer extends Object with ObjectivelyMVC's UI rendering layer.
Definition Renderer.h:70
SlideShowView cycles through a collection of Images with crossfade transitions.
Array * images
The images to display.
ImageView * current
The bottom ImageView, showing the current slide.
Uint32 slideDuration
The duration of each slide in milliseconds, excluding the fade transition.
Uint32 fadeDuration
The duration of the fade transition in milliseconds.
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
Definition View.h:134
void render(View *self, Renderer *renderer)
Renders this View using the given renderer.
Definition Control.c:179
View * initWithFrame(View *self, const SDL_Rect *frame)
Initializes this View with the specified frame.
Definition View.c:989