ObjectivelyMVC 0.1.0
Object oriented MVC framework for OpenGL, SDL2 and GNU C
ProgressBar.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#include <string.h>
26
27#include "ProgressBar.h"
28
29#define _Class _ProgressBar
30
31#pragma mark - Object
32
36static void dealloc(Object *self) {
37
38 ProgressBar *this = (ProgressBar *) self;
39
40 release(this->background);
41 release(this->foreground);
42 release(this->label);
43
44 free(this->labelFormat);
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 ProgressBar *this = (ProgressBar *) self;
59
60 double value = this->value;
61
62 const Inlet inlets[] = MakeInlets(
63 MakeInlet("background", InletTypeView, &this->background, NULL),
64 MakeInlet("foreground", InletTypeView, &this->foreground, NULL),
65 MakeInlet("label", InletTypeView, &this->label, NULL),
66 MakeInlet("labelFormat", InletTypeCharacters, &this->labelFormat, NULL),
67 MakeInlet("min", InletTypeDouble, &this->min, NULL),
68 MakeInlet("max", InletTypeDouble, &this->max, NULL),
69 MakeInlet("value", InletTypeDouble, &value, NULL)
70 );
71
72 $(self, bind, inlets, dictionary);
73
74 $(this, setValue, value);
75}
76
80static View *init(View *self) {
81 return (View *) $((ProgressBar *) self, initWithFrame, NULL);
82}
83
84#pragma mark - ProgressBar
85
90static void formatLabel(ProgressBar *self) {
91
92 char text[128];
93 snprintf(text, sizeof(text), self->labelFormat, self->value);
94
95 $(self->label, setText, text);
96}
97
102static ProgressBar *initWithFrame(ProgressBar *self, const SDL_Rect *frame) {
103
104 self = (ProgressBar *) super(View, self, initWithFrame, frame);
105 if (self) {
106
107 self->background = $(alloc(ImageView), initWithFrame, NULL);
108 assert(self->background);
109
110 $((View *) self->background, addClassName, "background");
111 $((View *) self, addSubview, (View *) self->background);
112
113 self->foreground = $(alloc(ImageView), initWithFrame, NULL);
114 assert(self->foreground);
115
116 $((View *) self->foreground, addClassName, "foreground");
117 $((View *) self, addSubview, (View *) self->foreground);
118
119 self->label = $(alloc(Text), initWithText, NULL, NULL);
120 assert(self->label);
121
122 $((View *) self, addSubview, (View *) self->label);
123
124 $(self, setLabelFormat, "%0.0lf%%");
125
126 self->value = -1.0;
127 self->max = 100.0;
128 }
129
130 return self;
131}
132
137static double progress(const ProgressBar *self) {
138 return 100.0 * self->value / (self->max - self->min);
139}
140
145static void setLabelFormat(ProgressBar *self, const char *labelFormat) {
146
147 if (self->labelFormat) {
148 free(self->labelFormat);
149 }
150
151 self->labelFormat = strdup(labelFormat);
152 $(self, formatLabel);
153}
154
159static void setValue(ProgressBar *self, double value) {
160
161 value = clamp(value, self->min, self->max);
162
163 const double delta = fabs(self->value - value);
164 if (delta > __DBL_EPSILON__) {
165 self->value = value;
166
167 const SDL_Rect bounds = $((View *) self, bounds);
168 const double frac = self->value / (self->max - self->min);
169
170 self->foreground->view.frame.w = bounds.w * frac;
171 self->view.needsLayout = true;
172
173 $(self, formatLabel);
174
175 if (self->delegate.didSetValue) {
176 self->delegate.didSetValue(self, self->value);
177 }
178 }
179}
180
181#pragma mark - Class lifecycle
182
186static void initialize(Class *clazz) {
187
188 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
189
190 ((ViewInterface *) clazz->interface)->awakeWithDictionary = awakeWithDictionary;
191 ((ViewInterface *) clazz->interface)->init = init;
192
193 ((ProgressBarInterface *) clazz->interface)->formatLabel = formatLabel;
194 ((ProgressBarInterface *) clazz->interface)->initWithFrame = initWithFrame;
195 ((ProgressBarInterface *) clazz->interface)->progress = progress;
196 ((ProgressBarInterface *) clazz->interface)->setLabelFormat = setLabelFormat;
197 ((ProgressBarInterface *) clazz->interface)->setValue = setValue;
198}
199
204Class *_ProgressBar(void) {
205 static Class *clazz;
206 static Once once;
207
208 do_once(&once, {
209 clazz = _initialize(&(const ClassDef) {
210 .name = "ProgressBar",
211 .superclass = _View(),
212 .instanceSize = sizeof(ProgressBar),
213 .interfaceOffset = offsetof(ProgressBar, interface),
214 .interfaceSize = sizeof(ProgressBarInterface),
216 });
217 });
218
219 return clazz;
220}
221
222#undef _Class
static void dealloc(Object *self)
Definition: ProgressBar.c:36
static void initialize(Class *clazz)
Definition: ProgressBar.c:186
A Progress bar.
@ InletTypeDouble
Definition: View+JSON.h:67
@ InletTypeCharacters
Definition: View+JSON.h:52
@ 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
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.
ImageViews render an Image in the context of a View hierarchy.
Definition: ImageView.h:43
Inlets enable inbound data binding of View attributes through JSON.
Definition: View+JSON.h:155
Label * initWithText(Label *self, const char *text, Font *font)
Initializes this Label with the given text and Font.
Definition: Label.c:96
The ProgressBar type.
Definition: ProgressBar.h:61
double min
The progress bounds.
Definition: ProgressBar.h:104
double value
The progress value.
Definition: ProgressBar.h:109
Text * label
The progress Text.
Definition: ProgressBar.h:94
ImageView * background
The background ImageView.
Definition: ProgressBar.h:78
double progress(const ProgressBar *self)
Definition: ProgressBar.c:137
Class * _ProgressBar(void)
The ProgressBar archetype.
Definition: ProgressBar.c:204
void setLabelFormat(ProgressBar *self, const char *labelFormat)
Changes this ProgressBar's label format and calls appropriate update functions.
Definition: ProgressBar.c:145
void formatLabel(ProgressBar *self)
Forces an update on this ProgressBar's label.
Definition: ProgressBar.c:90
char * labelFormat
The Label format, e.g. "%0.0lf".
Definition: ProgressBar.h:99
void setValue(const ProgressBar *self, double value)
Sets the value, which is clamped to min and max.
double max
Definition: ProgressBar.h:104
Text rendered with TrueType fonts.
Definition: Text.h:41
void setText(Text *self, const char *text)
Sets this Text's text.
Definition: Text.c:261
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
Definition: View.h:133
SDL_Rect bounds(const View *self)
Definition: View.c:394
_Bool bind(View *self, const Inlet *inlets, const Dictionary *dictionary)
Performs data binding for the Inlets described in dictionary.
_Bool needsLayout
If true, this View will layout its subviews before it is drawn.
Definition: View.h:221
Class * _View(void)
The View archetype.
Definition: View.c:1769
void addSubview(View *self, View *subview)
Adds a subview to this view, to be drawn above its siblings.
Definition: PageView.c:35
void addClassName(View *self, const char *className)
Adds the given class name to this View.
Definition: View.c:120
void awakeWithDictionary(View *self, const Dictionary *dictionary)
Wakes this View with the specified Dictionary.
Definition: Box.c:50
SDL_Rect frame
The frame, relative to the superview.
Definition: View.h:190