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 View * init (View *self)
 
static void initialize (Class *clazz)
 
static Control * initWithFrame (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 414 of file Control.c.

414 {
415 static Class *clazz;
416 static Once once;
417
418 do_once(&once, {
419 clazz = _initialize(&(const ClassDef) {
420 .name = "Control",
421 .superclass = _View(),
422 .instanceSize = sizeof(Control),
423 .interfaceSize = sizeof(ControlInterface),
424 .initialize = initialize,
425 });
426 });
427
428 return clazz;
429}
static void initialize(Class *clazz)
Definition Control.c:386
Class * _View(void)
Definition View.c:2336
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("bevel-dark-color", InletTypeColor, &this->bevelDarkColor, NULL),
98 MakeInlet("bevel-light-color", InletTypeColor, &this->bevelLightColor, NULL),
99 MakeInlet("selection", InletTypeEnum, &this->selection, (ident) ControlSelectionNames)
100 );
101
102 $(self, bind, inlets, (Dictionary *) style->attributes);
103}
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
@ InletTypeColor
Definition View+JSON.h:62
#define MakeInlets(...)
Creates a null-termianted array of Inlets.
Definition View+JSON.h:215
#define MakeInlet(name, type, dest, data)
Creates an Inlet with the specified parameters.
Definition View+JSON.h:210
Inlets enable inbound data binding of View attributes through JSON.
Definition View+JSON.h:149
Dictionary * attributes
Definition Style.h:59
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
Definition View.h:225

◆ awakeWithDictionary()

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

Definition at line 109 of file Control.c.

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

◆ becomeKeyResponder()

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

Definition at line 132 of file Control.c.

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

◆ captureEvent()

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

Definition at line 311 of file Control.c.

311 {
312 return false;
313}

◆ 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 125 of file Control.c.

125 {
126 return (View *) $((Control *) self, initWithFrame, NULL);
127}
static Control * initWithFrame(Control *self, const SDL_Rect *frame)
Definition Control.c:319

◆ initialize()

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

Definition at line 386 of file Control.c.

386 {
387
388 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
389
390 ((ViewInterface *) clazz->interface)->acceptsKeyResponder = acceptsKeyResponder;
391 ((ViewInterface *) clazz->interface)->acceptsTouchResponder = acceptsTouchResponder;
392 ((ViewInterface *) clazz->interface)->applyStyle = applyStyle;
393 ((ViewInterface *) clazz->interface)->awakeWithDictionary = awakeWithDictionary;
394 ((ViewInterface *) clazz->interface)->becomeKeyResponder = becomeKeyResponder;
395 ((ViewInterface *) clazz->interface)->init = init;
396 ((ViewInterface *) clazz->interface)->matchesSelector = matchesSelector;
397 ((ViewInterface *) clazz->interface)->render = render;
398 ((ViewInterface *) clazz->interface)->resignKeyResponder = resignKeyResponder;
399 ((ViewInterface *) clazz->interface)->respondToEvent = respondToEvent;
400
401 ((ControlInterface *) clazz->interface)->captureEvent = captureEvent;
402 ((ControlInterface *) clazz->interface)->initWithFrame = initWithFrame;
403 ((ControlInterface *) clazz->interface)->isDisabled = isDisabled;
404 ((ControlInterface *) clazz->interface)->isFocused = isFocused;
405 ((ControlInterface *) clazz->interface)->isHighlighted = isHighlighted;
406 ((ControlInterface *) clazz->interface)->isSelected = isSelected;
407 ((ControlInterface *) clazz->interface)->stateDidChange = stateDidChange;
408}
static bool acceptsKeyResponder(const View *self)
Definition Control.c:69
static View * init(View *self)
Definition Control.c:125
static void respondToEvent(View *self, const SDL_Event *event)
Definition Control.c:283
static bool matchesSelector(const View *self, const SimpleSelector *simpleSelector)
Definition Control.c:149
static bool captureEvent(Control *self, const SDL_Event *event)
Definition Control.c:311
static bool isHighlighted(const Control *self)
Definition Control.c:350
static void render(View *self, Renderer *renderer)
Definition Control.c:181
static void resignKeyResponder(View *self)
Definition Control.c:265
static bool isDisabled(const Control *self)
Definition Control.c:334
static bool acceptsTouchResponder(const View *self)
Definition Control.c:79
static bool isSelected(const Control *self)
Definition Control.c:358
bool isDisabled(const Control *self)
Definition Control.c:334
bool matchesSelector(const View *self, const SimpleSelector *simpleSelector)

◆ initWithFrame()

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

Definition at line 319 of file Control.c.

319 {
320
321 self = (Control *) super(View, self, initWithFrame, frame);
322 if (self) {
325 }
326
327 return self;
328}
W3C Color constants.
Definition Colors.h:37
SDL_Color Black
Definition Colors.h:46
SDL_Color Silver
Definition Colors.h:169
SDL_Color bevelLightColor
The bevel color for the lit edges.
Definition Control.h:112
SDL_Color bevelDarkColor
The bevel color for the shadowed edges.
Definition Control.h:106

◆ isDisabled()

static bool isDisabled ( const Control *  self)
static

Definition at line 334 of file Control.c.

334 {
336}
unsigned int state
The bit mask of ControlState.
Definition Control.h:117

◆ isFocused()

static bool isFocused ( const Control *  self)
static

Definition at line 342 of file Control.c.

342 {
344}

◆ isHighlighted()

static bool isHighlighted ( const Control *  self)
static

Definition at line 350 of file Control.c.

350 {
352}
@ ControlStateHighlighted
Definition Control.h:67

◆ isSelected()

static bool isSelected ( const Control *  self)
static

Definition at line 358 of file Control.c.

358 {
360}
@ 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 149 of file Control.c.

149 {
150
151 assert(simpleSelector);
152
153 const Control *this = (Control *) self;
154
155 switch (simpleSelector->type) {
157 if (strcmp("highlighted", simpleSelector->pattern) == 0) {
158 return $(this, isHighlighted);
159 } else if (strcmp("disabled", simpleSelector->pattern) == 0) {
160 return $(this, isDisabled);
161 } else if (strcmp("selected", simpleSelector->pattern) == 0) {
162 return $(this, isSelected);
163 } else if (strcmp("focused", simpleSelector->pattern) == 0) {
164 return $(this, isFocused);
165 } else if (strcmp("single", simpleSelector->pattern) == 0) {
166 return this->selection == ControlSelectionSingle;
167 } else if (strcmp("multiple", simpleSelector->pattern) == 0) {
168 return this->selection == ControlSelectionMultiple;
169 }
170 break;
171 default:
172 break;
173 }
174
175 return super(View, self, matchesSelector, simpleSelector);
176}
@ 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 181 of file Control.c.

181 {
182
183 super(View, self, render, renderer);
184
185 Control *this = (Control *) self;
186
187 const SDL_Rect frame = $(self, renderFrame);
188
189 if (self->borderRadius > 0) {
190
191 if (this->bevel == ControlBevelInset) {
192 $(renderer, drawBevel, &frame, self->borderRadius, 1, &this->bevelDarkColor, &this->bevelLightColor);
193 } else if (this->bevel == ControlBevelOutset) {
194 $(renderer, drawBevel, &frame, self->borderRadius, 1, &this->bevelLightColor, &this->bevelDarkColor);
195 }
196
197 if (this->state & ControlStateFocused) {
198 $(renderer, drawRoundedRect, &frame, self->borderRadius, 1, &Colors.Charcoal);
199 }
200
201 } else {
202
203 if (this->bevel == ControlBevelInset) {
204
205 SDL_Point points[3];
206
207 points[0].x = frame.x;
208 points[0].y = frame.y + frame.h;
209
210 points[1].x = frame.x + frame.w;
211 points[1].y = frame.y + frame.h;
212
213 points[2].x = frame.x + frame.w;
214 points[2].y = frame.y;
215
216 $(renderer, drawLines, points, lengthof(points), &this->bevelLightColor);
217
218 points[0].x = frame.x;
219 points[0].y = frame.y + frame.h;
220
221 points[1].x = frame.x;
222 points[1].y = frame.y;
223
224 points[2].x = frame.x + frame.w;
225 points[2].y = frame.y;
226
227 $(renderer, drawLines, points, lengthof(points), &this->bevelDarkColor);
228
229 } else if (this->bevel == ControlBevelOutset) {
230
231 SDL_Point points[3];
232
233 points[0].x = frame.x;
234 points[0].y = frame.y + frame.h;
235
236 points[1].x = frame.x + frame.w;
237 points[1].y = frame.y + frame.h;
238
239 points[2].x = frame.x + frame.w;
240 points[2].y = frame.y;
241
242 $(renderer, drawLines, points, lengthof(points), &this->bevelDarkColor);
243
244 points[0].x = frame.x;
245 points[0].y = frame.y + frame.h;
246
247 points[1].x = frame.x;
248 points[1].y = frame.y;
249
250 points[2].x = frame.x + frame.w;
251 points[2].y = frame.y;
252
253 $(renderer, drawLines, points, lengthof(points), &this->bevelLightColor);
254 }
255
256 if (this->state & ControlStateFocused) {
257 $(renderer, drawRect, &frame, &Colors.Charcoal);
258 }
259 }
260}
@ 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:277
static void drawRoundedRect(const Renderer *self, const SDL_Rect *rect, int radius, int width, const SDL_Color *color)
Definition Renderer.c:407
static void drawRect(const Renderer *self, const SDL_Rect *rect, const SDL_Color *color)
Definition Renderer.c:365
static void drawBevel(const Renderer *self, const SDL_Rect *rect, int radius, int width, const SDL_Color *topLeft, const SDL_Color *bottomRight)
Definition Renderer.c:247
static SDL_Rect renderFrame(const View *self)
Definition View.c:1629
SDL_Color Charcoal
Definition Colors.h:53
int borderRadius
The corner radius applied to the background, border and bevel.
Definition View.h:281

◆ resignKeyResponder()

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

Definition at line 265 of file Control.c.

265 {
266
267 Control *this = (Control *) self;
268
269 if ($(this, isHighlighted) || $(this, isFocused)) {
270
271 this->state &= ~ControlStateHighlighted;
272 this->state &= ~ControlStateFocused;
273
274 $(this, stateDidChange);
275 }
276
277 super(View, self, resignKeyResponder);
278}

◆ respondToEvent()

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

Definition at line 283 of file Control.c.

283 {
284
285 Control *this = (Control *) self;
286
287 retain(self);
288
289 const ControlState state = (ControlState) this->state;
290 if (!(state & ControlStateDisabled)) {
291 if ($(this, captureEvent, event)) {
292 if (this->state != state) {
293 $(this, stateDidChange);
294 }
295 release(self);
296 return;
297 }
298 }
299
300 super(View, self, respondToEvent, event);
301
302 release(self);
303}
ControlState
Control states, which are bit-masked.
Definition Control.h:65

◆ stateDidChange()

static void stateDidChange ( Control *  self)
static

Definition at line 366 of file Control.c.

366 {
367
368 View *this = (View *) self;
369
370 if (self->state & ControlStateFocused) {
371 $(this, emitViewEvent, ViewEventFocus, NULL);
372 } else {
373 $(this, emitViewEvent, ViewEventBlur, NULL);
374 }
375
376 $(this, invalidateStyle);
377
378 $(this, setNeedsLayout);
379}
@ 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:1092
static void setNeedsLayout(View *self)
Definition View.c:1865
static void emitViewEvent(View *self, ViewEvent code, ident data)
Definition View.c:794

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.