ObjectivelyMVC
Object oriented MVC framework for SDL3 and GNU C
Loading...
Searching...
No Matches
Control.c File Reference
#include <assert.h>
#include "Control.h"

Go to the source code of this file.

Macros

#define _Class   _Control
 

Functions

Class * _Control (void)
 
static bool acceptsKeyResponder (const View *self)
 
static bool acceptsTouchResponder (const View *self)
 
static void applyStyle (View *self, const Style *style)
 
static void awakeWithDictionary (View *self, const Dictionary *dictionary)
 
static void becomeKeyResponder (View *self)
 
static bool captureEvent (Control *self, const SDL_Event *event)
 
static void dealloc (Object *self)
 
static Viewinit (View *self)
 
static void initialize (Class *clazz)
 
static ControlinitWithFrame (Control *self, const SDL_Rect *frame)
 
static bool isDisabled (const Control *self)
 
static bool isFocused (const Control *self)
 
static bool isHighlighted (const Control *self)
 
static bool isSelected (const Control *self)
 
static bool matchesSelector (const View *self, const SimpleSelector *simpleSelector)
 
static void render (View *self, Renderer *renderer)
 
static void resignKeyResponder (View *self)
 
static void respondToEvent (View *self, const SDL_Event *event)
 
static void stateDidChange (Control *self)
 

Variables

const EnumName ControlBevelNames []
 
const EnumName ControlSelectionNames []
 
const EnumName ControlStateNames []
 

Macro Definition Documentation

◆ _Class

#define _Class   _Control

Definition at line 48 of file Control.c.

Function Documentation

◆ _Control()

Class * _Control ( void  )

Definition at line 391 of file Control.c.

391 {
392 static Class *clazz;
393 static Once once;
394
395 do_once(&once, {
396 clazz = _initialize(&(const ClassDef) {
397 .name = "Control",
398 .superclass = _View(),
399 .instanceSize = sizeof(Control),
400 .interfaceOffset = offsetof(Control, interface),
401 .interfaceSize = sizeof(ControlInterface),
403 });
404 });
405
406 return clazz;
407}
static void initialize(Class *clazz)
Definition Control.c:363
Class * _View(void)
Definition View.c:2067
Controls are Views which capture and respond to events.
Definition Control.h:83

◆ acceptsKeyResponder()

static bool acceptsKeyResponder ( const View self)
static
See also
View::acceptsKeyResponder(const View *)

Definition at line 69 of file Control.c.

69 {
70
71 Control *this = (Control *) self;
72
73 return (this->state & ControlStateDisabled) == 0;
74}
@ ControlStateDisabled
Definition Control.h:70

◆ acceptsTouchResponder()

static bool acceptsTouchResponder ( const View self)
static
See also
View::acceptsTouchResponder(const View *)

Definition at line 79 of file Control.c.

79 {
80
81 Control *this = (Control *) self;
82
83 return (this->state & ControlStateDisabled) == 0;
84}

◆ applyStyle()

static void applyStyle ( View self,
const Style style 
)
static
See also
View::applyStyle(View *, const Style *)

Definition at line 89 of file Control.c.

89 {
90
91 super(View, self, applyStyle, style);
92
93 Control *this = (Control *) self;
94
95 const Inlet inlets[] = MakeInlets(
96 MakeInlet("bevel", InletTypeEnum, &this->bevel, (ident) ControlBevelNames),
97 MakeInlet("selection", InletTypeEnum, &this->selection, (ident) ControlSelectionNames)
98 );
99
100 $(self, bind, inlets, (Dictionary *) style->attributes);
101}
const EnumName ControlBevelNames[]
Definition Control.c:28
const EnumName ControlSelectionNames[]
Definition Control.c:34
static void applyStyle(View *self, const Style *style)
Definition Control.c:89
@ InletTypeEnum
Definition View+JSON.h:75
#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
Inlets enable inbound data binding of View attributes through JSON.
Definition View+JSON.h:155
Dictionary * attributes
Definition Style.h:59
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
Definition View.h:134

◆ awakeWithDictionary()

static void awakeWithDictionary ( View self,
const Dictionary *  dictionary 
)
static

Definition at line 107 of file Control.c.

107 {
108
109 super(View, self, awakeWithDictionary, dictionary);
110
111 Control *this = (Control *) self;
112
113 const Inlet inlets[] = MakeInlets(
114 MakeInlet("state", InletTypeEnum, &this->state, (ident) ControlStateNames)
115 );
116
117 $(self, bind, inlets, dictionary);
118}
static void awakeWithDictionary(View *self, const Dictionary *dictionary)
Definition Control.c:107
const EnumName ControlStateNames[]
Definition Control.c:40

◆ becomeKeyResponder()

static void becomeKeyResponder ( View self)
static
See also
View::becomeKeyResponder(View *)

Definition at line 130 of file Control.c.

130 {
131
132 Control *this = (Control *) self;
133
134 if (!$(this, isFocused)) {
135
136 this->state |= ControlStateFocused;
137
138 $(this, stateDidChange);
139 }
140
141 super(View, self, becomeKeyResponder);
142}
static void becomeKeyResponder(View *self)
Definition Control.c:130
static void stateDidChange(Control *self)
Definition Control.c:343
static bool isFocused(const Control *self)
Definition Control.c:319
@ ControlStateFocused
Definition Control.h:69

◆ captureEvent()

static bool captureEvent ( Control self,
const SDL_Event *  event 
)
static

Definition at line 289 of file Control.c.

289 {
290 return false;
291}

◆ dealloc()

static void dealloc ( Object *  self)
static
See also
Object::dealloc(Object *)

Definition at line 55 of file Control.c.

55 {
56
57 Control *this = (Control *) self;
58
59 this->state = ControlStateDefault;
60
61 super(Object, self, dealloc);
62}
static void dealloc(Object *self)
Definition Control.c:55
@ ControlStateDefault
Definition Control.h:66

◆ init()

static View * init ( View self)
static
See also
View::init(View *)

Definition at line 123 of file Control.c.

123 {
124 return (View *) $((Control *) self, initWithFrame, NULL);
125}
static Control * initWithFrame(Control *self, const SDL_Rect *frame)
Definition Control.c:297

◆ initialize()

static void initialize ( Class *  clazz)
static
See also
Class::initialize(Class *)

Definition at line 363 of file Control.c.

363 {
364
365 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
366
367 ((ViewInterface *) clazz->interface)->acceptsKeyResponder = acceptsKeyResponder;
368 ((ViewInterface *) clazz->interface)->acceptsTouchResponder = acceptsTouchResponder;
369 ((ViewInterface *) clazz->interface)->applyStyle = applyStyle;
370 ((ViewInterface *) clazz->interface)->awakeWithDictionary = awakeWithDictionary;
371 ((ViewInterface *) clazz->interface)->becomeKeyResponder = becomeKeyResponder;
372 ((ViewInterface *) clazz->interface)->init = init;
373 ((ViewInterface *) clazz->interface)->matchesSelector = matchesSelector;
374 ((ViewInterface *) clazz->interface)->render = render;
375 ((ViewInterface *) clazz->interface)->resignKeyResponder = resignKeyResponder;
376 ((ViewInterface *) clazz->interface)->respondToEvent = respondToEvent;
377
378 ((ControlInterface *) clazz->interface)->captureEvent = captureEvent;
379 ((ControlInterface *) clazz->interface)->initWithFrame = initWithFrame;
380 ((ControlInterface *) clazz->interface)->isDisabled = isDisabled;
381 ((ControlInterface *) clazz->interface)->isFocused = isFocused;
382 ((ControlInterface *) clazz->interface)->isHighlighted = isHighlighted;
383 ((ControlInterface *) clazz->interface)->isSelected = isSelected;
384 ((ControlInterface *) clazz->interface)->stateDidChange = stateDidChange;
385}
static bool acceptsKeyResponder(const View *self)
Definition Control.c:69
static View * init(View *self)
Definition Control.c:123
static void respondToEvent(View *self, const SDL_Event *event)
Definition Control.c:266
static bool matchesSelector(const View *self, const SimpleSelector *simpleSelector)
Definition Control.c:147
static bool captureEvent(Control *self, const SDL_Event *event)
Definition Control.c:289
static bool isHighlighted(const Control *self)
Definition Control.c:327
static void render(View *self, Renderer *renderer)
Definition Control.c:179
static void resignKeyResponder(View *self)
Definition Control.c:248
static bool isDisabled(const Control *self)
Definition Control.c:311
static bool acceptsTouchResponder(const View *self)
Definition Control.c:79
static bool isSelected(const Control *self)
Definition Control.c:335
bool isDisabled(const Control *self)
Definition Control.c:311
bool matchesSelector(const View *self, const SimpleSelector *simpleSelector)

◆ initWithFrame()

static Control * initWithFrame ( Control self,
const SDL_Rect *  frame 
)
static

Definition at line 297 of file Control.c.

297 {
298
299 self = (Control *) super(View, self, initWithFrame, frame);
300 if (self) {
301
302 }
303
304 return self;
305}

◆ isDisabled()

static bool isDisabled ( const Control self)
static

Definition at line 311 of file Control.c.

311 {
313}
unsigned int state
The bit mask of ControlState.
Definition Control.h:104

◆ isFocused()

static bool isFocused ( const Control self)
static

Definition at line 319 of file Control.c.

319 {
321}

◆ isHighlighted()

static bool isHighlighted ( const Control self)
static

Definition at line 327 of file Control.c.

327 {
329}
@ ControlStateHighlighted
Definition Control.h:67

◆ isSelected()

static bool isSelected ( const Control self)
static

Definition at line 335 of file Control.c.

335 {
337}
@ ControlStateSelected
Definition Control.h:68

◆ matchesSelector()

static bool matchesSelector ( const View self,
const SimpleSelector simpleSelector 
)
static
See also
View::matchesSelector(const View *, const SimpleSelector *)

Definition at line 147 of file Control.c.

147 {
148
149 assert(simpleSelector);
150
151 const Control *this = (Control *) self;
152
153 switch (simpleSelector->type) {
155 if (strcmp("highlighted", simpleSelector->pattern) == 0) {
156 return $(this, isHighlighted);
157 } else if (strcmp("disabled", simpleSelector->pattern) == 0) {
158 return $(this, isDisabled);
159 } else if (strcmp("selected", simpleSelector->pattern) == 0) {
160 return $(this, isSelected);
161 } else if (strcmp("focused", simpleSelector->pattern) == 0) {
162 return $(this, isFocused);
163 } else if (strcmp("single", simpleSelector->pattern) == 0) {
164 return this->selection == ControlSelectionSingle;
165 } else if (strcmp("multiple", simpleSelector->pattern) == 0) {
166 return this->selection == ControlSelectionMultiple;
167 }
168 break;
169 default:
170 break;
171 }
172
173 return super(View, self, matchesSelector, simpleSelector);
174}
@ ControlSelectionMultiple
Definition Control.h:57
@ ControlSelectionSingle
Definition Control.h:56
@ SimpleSelectorTypePseudo
SimpleSelectorType type
The SimpleSelectorType.
char * pattern
The pattern, as provided by the user.

◆ render()

static void render ( View self,
Renderer renderer 
)
static
See also
View::render(View *, Renderer *)

Definition at line 179 of file Control.c.

179 {
180
181 super(View, self, render, renderer);
182
183 Control *this = (Control *) self;
184
185 const SDL_Rect frame = $(self, renderFrame);
186
187 if (this->bevel == ControlBevelInset) {
188
189 SDL_Point points[3];
190
191 points[0].x = frame.x;
192 points[0].y = frame.y + frame.h;
193
194 points[1].x = frame.x + frame.w;
195 points[1].y = frame.y + frame.h;
196
197 points[2].x = frame.x + frame.w;
198 points[2].y = frame.y;
199
200 $(renderer, drawLines, points, lengthof(points), &Colors.Silver);
201
202 points[0].x = frame.x;
203 points[0].y = frame.y + frame.h;
204
205 points[1].x = frame.x;
206 points[1].y = frame.y;
207
208 points[2].x = frame.x + frame.w;
209 points[2].y = frame.y;
210
211 $(renderer, drawLines, points, lengthof(points), &Colors.Black);
212
213 } else if (this->bevel == ControlBevelOutset) {
214
215 SDL_Point points[3];
216
217 points[0].x = frame.x;
218 points[0].y = frame.y + frame.h;
219
220 points[1].x = frame.x + frame.w;
221 points[1].y = frame.y + frame.h;
222
223 points[2].x = frame.x + frame.w;
224 points[2].y = frame.y;
225
226 $(renderer, drawLines, points, lengthof(points), &Colors.Black);
227
228 points[0].x = frame.x;
229 points[0].y = frame.y + frame.h;
230
231 points[1].x = frame.x;
232 points[1].y = frame.y;
233
234 points[2].x = frame.x + frame.w;
235 points[2].y = frame.y;
236
237 $(renderer, drawLines, points, lengthof(points), &Colors.Silver);
238 }
239
240 if (this->state & ControlStateFocused) {
241 $(renderer, drawRect, &frame, &Colors.Charcoal);
242 }
243}
@ ControlBevelInset
Definition Control.h:45
@ ControlBevelOutset
Definition Control.h:46
static void drawLines(const Renderer *self, const SDL_Point *points, size_t count, const SDL_Color *color)
Definition Renderer.c:125
static void drawRect(const Renderer *self, const SDL_Rect *rect, const SDL_Color *color)
Definition Renderer.c:169
static SDL_Rect renderFrame(const View *self)
Definition View.c:1455
W3C Color constants.
Definition Colors.h:37
SDL_Color Charcoal
Definition Colors.h:53
SDL_Color Black
Definition Colors.h:46
SDL_Color Silver
Definition Colors.h:169

◆ resignKeyResponder()

static void resignKeyResponder ( View self)
static
See also
View::resignKeyResponder(View *)

Definition at line 248 of file Control.c.

248 {
249
250 Control *this = (Control *) self;
251
252 if ($(this, isHighlighted) || $(this, isFocused)) {
253
254 this->state &= ~ControlStateHighlighted;
255 this->state &= ~ControlStateFocused;
256
257 $(this, stateDidChange);
258 }
259
260 super(View, self, resignKeyResponder);
261}

◆ respondToEvent()

static void respondToEvent ( View self,
const SDL_Event *  event 
)
static
See also
View::respondToEvent(View *, SDL_Event *)

Definition at line 266 of file Control.c.

266 {
267
268 Control *this = (Control *) self;
269
270 const ControlState state = (ControlState) this->state;
271 if (!(state & ControlStateDisabled)) {
272 if ($(this, captureEvent, event)) {
273 if (this->state != state) {
274 $(this, stateDidChange);
275 }
276 return;
277 }
278 }
279
280 super(View, self, respondToEvent, event);
281}
ControlState
Control states, which are bit-masked.
Definition Control.h:65

◆ stateDidChange()

static void stateDidChange ( Control self)
static

Definition at line 343 of file Control.c.

343 {
344
345 View *this = (View *) self;
346
347 if (self->state & ControlStateFocused) {
348 $(this, emitViewEvent, ViewEventFocus, NULL);
349 } else {
350 $(this, emitViewEvent, ViewEventBlur, NULL);
351 }
352
353 $(this, invalidateStyle);
354
355 this->needsLayout = true;
356}
@ ViewEventFocus
A Control's state has focus.
Definition Types.h:120
@ ViewEventBlur
A Control has lost focus.
Definition Types.h:105
static void invalidateStyle(View *self)
Definition View.c:1033
static void emitViewEvent(View *self, ViewEvent code, ident data)
Definition View.c:736

Variable Documentation

◆ ControlBevelNames

const EnumName ControlBevelNames[]
Initial value:
= MakeEnumNames(
MakeEnumAlias(ControlBevelNone, none),
MakeEnumAlias(ControlBevelInset, inset),
MakeEnumAlias(ControlBevelOutset, outset)
)
@ ControlBevelNone
Definition Control.h:44

Definition at line 28 of file Control.c.

◆ ControlSelectionNames

const EnumName ControlSelectionNames[]
Initial value:
= MakeEnumNames(
MakeEnumAlias(ControlSelectionNone, none),
MakeEnumAlias(ControlSelectionSingle, single),
MakeEnumAlias(ControlSelectionMultiple, multiple)
)
@ ControlSelectionNone
Definition Control.h:55

Definition at line 34 of file Control.c.

◆ ControlStateNames

const EnumName ControlStateNames[]
Initial value:
= MakeEnumNames(
MakeEnumAlias(ControlStateDefault, default),
MakeEnumAlias(ControlStateHighlighted, highlighted),
MakeEnumAlias(ControlStateSelected, selected),
MakeEnumAlias(ControlStateFocused, focused),
MakeEnumAlias(ControlStateDisabled, disabled)
)

Definition at line 40 of file Control.c.