ObjectivelyMVC
Object oriented MVC framework for SDL3 and GNU C
Loading...
Searching...
No Matches
View.c File Reference
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <Objectively.h>
#include "Log.h"
#include "View.h"
#include "ViewController.h"
#include "WindowController.h"
#include "Window.h"

Go to the source code of this file.

Data Structures

struct  Overflow
 

Macros

#define _Class   _View
 

Functions

static void _applyThemeIfNeeded (View *view, ident data)
 ViewEnumerator adapter for applyThemeIfNeeded.
 
static bool _bind (View *self, const Inlet *inlets, const Dictionary *dictionary)
 
static void _draw (View *view, ident data)
 ViewEnumerator adapter for draw.
 
static Set * _select (View *self, const char *rule)
 
Class * _View (void)
 
static bool acceptsKeyResponder (const View *self)
 
static bool acceptsTouchResponder (const View *self)
 
static void addClassName (View *self, const char *className)
 
static void addSubview (View *self, View *subview)
 
static void addSubviewRelativeTo (View *self, View *subview, View *other, ViewPosition position)
 
static ViewancestorWithIdentifier (const View *self, const char *identifier)
 
static void applyStyle (View *self, const Style *style)
 
static void applyTheme (View *self, const Theme *theme)
 
static void applyThemeIfNeeded (View *self, const Theme *theme)
 
static void attachStylesheet (View *self, SDL_Window *window)
 
static void awakeWithCharacters (View *self, const char *chars)
 
static void awakeWithData (View *self, const Data *data)
 
static void awakeWithDictionary (View *self, const Dictionary *dictionary)
 
static void awakeWithResource (View *self, const Resource *resource)
 
static void awakeWithResourceName (View *self, const char *name)
 
static void becomeKeyResponder (View *self)
 
static void becomeTouchResponder (View *self)
 
static SDL_Rect bounds (const View *self)
 
static void bringSubviewToFront (View *self, View *subview)
 
static void clearWarnings (const View *self, WarningType type)
 
static bool clearWarnings_predicate (const ident obj, ident data)
 Filter Predicate for clearWarnings.
 
static SDL_Rect clippingFrame (const View *self)
 
static bool containsPoint (const View *self, const SDL_Point *point)
 
static void dealloc (Object *self)
 
static int depth (const View *self)
 
static ViewdescendantWithIdentifier (const View *self, const char *identifier)
 
static String * description (const Object *self)
 
static void detachStylesheet (View *self, SDL_Window *window)
 
static void didMoveToWindow (View *self, SDL_Window *window)
 
static bool didReceiveEvent (const View *self, const SDL_Event *event)
 
static void draw (View *self, Renderer *renderer)
 
static void emitViewEvent (View *self, ViewEvent code, ident data)
 
static void enumerate (View *self, ViewEnumerator enumerator, ident data)
 
static void enumerateAdjacent (const View *self, ViewEnumerator enumerator, ident data)
 
static void enumerateAncestors (const View *self, ViewEnumerator enumerator, ident data)
 
static void enumerateDescendants (const View *self, ViewEnumerator enumerator, ident data)
 
static void enumerateSelection (View *self, const char *rule, ViewEnumerator enumerator, ident data)
 
static void enumerateSiblings (const View *self, ViewEnumerator enumerator, ident data)
 
static void enumerateSubviews (const View *self, ViewEnumerator enumerator, ident data)
 
static void enumerateSuperview (const View *self, ViewEnumerator enumerator, ident data)
 
static void enumerateVisible (View *self, ViewEnumerator enumerator, ident data)
 
static bool filterViewEvents (void *data, SDL_Event *event)
 
static bool hasClassName (const View *self, const char *className)
 
static bool hasClassName_predicate (const ident obj, ident data)
 Predicate for hasClassName.
 
static bool hasOverflow (const View *self)
 
static void hasOverflow_enumerate (View *view, ident data)
 ViewEnumerator for hasOverflow.
 
static ViewhitTest (const View *self, const SDL_Point *point)
 
static Viewinit (View *self)
 
static void initialize (Class *clazz)
 
static ViewinitWithFrame (View *self, const SDL_Rect *frame)
 
static void invalidateStyle (View *self)
 
static void invalidateStyle_enumerate (View *view, ident data)
 ViewEnumerator for invalidateStyle.
 
static bool isContainer (const View *self)
 
static bool isDescendantOfView (const View *self, const View *view)
 
static bool isKeyResponder (const View *self)
 
static bool isTouchResponder (const View *self)
 
static bool isVisible (const View *self)
 
static void layoutIfNeeded (View *self)
 
static void layoutIfNeeded_enumerate (View *subview, ident data)
 ViewEnumerator for layoutIfNeeded recursion.
 
static void layoutSubviews (View *self)
 
static bool matchesSelector (const View *self, const SimpleSelector *simpleSelector)
 
static void moveToWindow (View *self, SDL_Window *window)
 
static void moveToWindow_enumerate (View *subview, ident data)
 ViewEnumerator for moveToWindow recursion.
 
static void nullifySuperview (View *subview, ident data)
 ViewEnumerator to null out superview pointers during parent dealloc.
 
static String * path (const View *self)
 
static void removeAllClassNames (View *self)
 
static void removeAllSubviews (View *self)
 
static void removeAllSubviews_enumerate (const Array *array, ident obj, ident data)
 ArrayEnumerator for removeAllSubviews.
 
static void removeClassName (View *self, const char *className)
 
static void removeFromSuperview (View *self)
 
static void removeSubview (View *self, View *subview)
 
static void render (View *self, Renderer *renderer)
 
static void renderDeviceDidReset (View *self)
 
static void renderDeviceDidReset_enumerate (View *subview, ident data)
 ViewEnumerator for renderDeviceDidReset recursion.
 
static void renderDeviceWillReset (View *self)
 
static void renderDeviceWillReset_enumerate (View *subview, ident data)
 ViewEnumerator for renderDeviceWillReset recursion.
 
static SDL_Rect renderFrame (const View *self)
 
static void replaceSubview (View *self, View *subview, View *replacement)
 
static void resignKeyResponder (View *self)
 
static void resignTouchResponder (View *self)
 
static void resize (View *self, const SDL_Size *size)
 
static void resolve (View *self, Outlet *outlets)
 
static void respondToEvent (View *self, const SDL_Event *event)
 
static ViewselectFirst (View *self, const char *rule)
 
static SDL_Size size (const View *self)
 
static SDL_Size sizeThatContains (const View *self)
 
static SDL_Size sizeThatFills (const View *self)
 
static SDL_Size sizeThatFits (const View *self)
 
static void sizeToContain (View *self)
 
static void sizeToFill (View *self)
 
static void sizeToFit (View *self)
 
static ViewsubviewWithIdentifier (const View *self, const char *identifier)
 
static void updateBindings (View *self)
 
static void updateBindings_enumerate (View *subview, ident data)
 ViewEnumerator for updateBindings recursion.
 
static SDL_Rect viewport (const View *self)
 
static ViewviewWithCharacters (const char *chars, Outlet *outlets)
 
static ViewviewWithData (const Data *data, Outlet *outlets)
 
static ViewviewWithDictionary (const Dictionary *dictionary, Outlet *outlets)
 
static ViewviewWithResource (const Resource *resource, Outlet *outlets)
 
static ViewviewWithResourceName (const char *name, Outlet *outlets)
 
static Array * visibleSubviews (const View *self)
 
static bool visibleSubviews_filter (ident obj, ident data)
 Predicate for visibleSubviews.
 
static void warn (View *self, WarningType type, const char *fmt,...)
 
static void willMoveToWindow (View *self, SDL_Window *window)
 

Variables

Uint32 MVC_NOTIFICATION_EVENT
 
Uint32 MVC_VIEW_EVENT
 
const EnumName ViewAlignmentNames []
 
const EnumName ViewAutoresizingNames []
 

Macro Definition Documentation

◆ _Class

#define _Class   _View

Definition at line 68 of file View.c.

Function Documentation

◆ _applyThemeIfNeeded()

static void _applyThemeIfNeeded ( View view,
ident  data 
)
static

ViewEnumerator adapter for applyThemeIfNeeded.

Definition at line 313 of file View.c.

313 {
314 applyThemeIfNeeded(view, (const Theme *) data);
315}
static void applyThemeIfNeeded(View *self, const Theme *theme)
Definition View.c:317
The Theme type.
Definition Theme.h:51

◆ _bind()

static bool _bind ( View self,
const Inlet inlets,
const Dictionary *  dictionary 
)
static

Definition at line 475 of file View.c.

475 {
476
477 if (inlets) {
478 if (bindInlets(inlets, dictionary)) {
479 self->needsApplyTheme = true;
480 self->needsLayout = true;
481 return true;
482 }
483 }
484
485 return false;
486}
bool bindInlets(const Inlet *inlets, const Dictionary *dictionary)
Binds each Inlet specified in inlets to the data provided in dictionary.
Definition View+JSON.c:327
bool needsApplyTheme
If true, this View will apply the Theme before it is drawn.
Definition View.h:217
bool needsLayout
If true, this View will layout its subviews before it is drawn.
Definition View.h:222

◆ _draw()

static void _draw ( View view,
ident  data 
)
static

ViewEnumerator adapter for draw.

Definition at line 705 of file View.c.

705 {
706 draw(view, (Renderer *) data);
707}
static void draw(View *self, Renderer *renderer)
Definition View.c:709
Renderer extends Object with ObjectivelyMVC's UI rendering layer.
Definition Renderer.h:70

◆ _select()

static Set * _select ( View self,
const char *  rule 
)
static

Definition at line 1610 of file View.c.

1610 {
1611
1612 Selector *selector = $(alloc(Selector), initWithRule, rule);
1613 assert(selector);
1614
1615 Set *selection = $(selector, select, self);
1616
1617 release(selector);
1618 return selection;
1619}
static Selector * initWithRule(Selector *self, const char *rule)
Definition Selector.c:190
Selectors are comprised of one or more SelectorSequences.
Definition Selector.h:49

◆ _View()

Class * _View ( void  )

Definition at line 2056 of file View.c.

2056 {
2057 static Class *clazz;
2058 static Once once;
2059
2060 do_once(&once, {
2061 clazz = _initialize(&(const ClassDef) {
2062 .name = "View",
2063 .superclass = _Object(),
2064 .instanceSize = sizeof(View),
2065 .interfaceOffset = offsetof(View, interface),
2066 .interfaceSize = sizeof(ViewInterface),
2068 });
2069 });
2070
2071 return clazz;
2072}
static void initialize(Class *clazz)
Definition View.c:1949
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
Definition View.h:134

◆ acceptsKeyResponder()

static bool acceptsKeyResponder ( const View self)
static

Definition at line 143 of file View.c.

143 {
144 return false;
145}

◆ acceptsTouchResponder()

static bool acceptsTouchResponder ( const View self)
static

Definition at line 151 of file View.c.

151 {
152 return false;
153}

◆ addClassName()

static void addClassName ( View self,
const char *  className 
)
static

Definition at line 159 of file View.c.

159 {
160
161 if (className) {
162
163 String *string = $$(String, stringWithCharacters, className);
164 assert(string);
165
166 $(self->classNames, addObject, string);
167 release(string);
168
169 $(self, invalidateStyle);
170 }
171}
static void invalidateStyle(View *self)
Definition View.c:1022
Set * classNames
The class names.
Definition View.h:176

◆ addSubview()

static void addSubview ( View self,
View subview 
)
static

Definition at line 177 of file View.c.

177 {
178 $(self, addSubviewRelativeTo, subview, NULL, ViewPositionAfter);
179}
static void addSubviewRelativeTo(View *self, View *subview, View *other, ViewPosition position)
Definition View.c:185
@ ViewPositionAfter
Definition View.h:121

◆ addSubviewRelativeTo()

static void addSubviewRelativeTo ( View self,
View subview,
View other,
ViewPosition  position 
)
static

Definition at line 185 of file View.c.

185 {
186
187 assert(subview);
188 assert(subview != other);
189
190 retain(subview);
191
192 $(subview, removeFromSuperview);
193
194 if (other && other->superview == self) {
195
196 const Array *subviews = (Array *) self->subviews;
197 const ssize_t index = $(subviews, indexOfObject, other);
198
199 if (position == ViewPositionAfter) {
200 if (index == (ssize_t) (subviews->count - 1)) {
201 $(self->subviews, addObject, subview);
202 } else {
203 $(self->subviews, insertObjectAtIndex, subview, index + 1);
204 }
205 } else {
206 $(self->subviews, insertObjectAtIndex, subview, index);
207 }
208 } else {
209 $(self->subviews, addObject, subview);
210 }
211
212 release(subview);
213
214 subview->superview = self;
215
216 $(subview, moveToWindow, self->window);
217
218 $(subview, invalidateStyle);
219
220 self->needsLayout = true;
221}
static void moveToWindow(View *self, SDL_Window *window)
Definition View.c:1251
static void removeFromSuperview(View *self)
Definition View.c:1350
View * superview
The super View.
Definition View.h:259
Array * subviews
The immediate subviews.
Definition View.h:253
SDL_Window * window
The window.
Definition View.h:277

◆ ancestorWithIdentifier()

static View * ancestorWithIdentifier ( const View self,
const char *  identifier 
)
static

Definition at line 227 of file View.c.

227 {
228
229 assert(identifier);
230
231 View *view = (View *) self;
232 while (view) {
233 if (view->identifier) {
234 if (strcmp(identifier, view->identifier) == 0) {
235 return view;
236 }
237 }
238 view = view->superview;
239 }
240
241 return NULL;
242}
char * identifier
An optional identifier.
Definition View.h:202

◆ applyStyle()

static void applyStyle ( View self,
const Style style 
)
static

Definition at line 248 of file View.c.

248 {
249
250 assert(style);
251
252 const Inlet inlets[] = MakeInlets(
253 MakeInlet("alignment", InletTypeEnum, &self->alignment, (ident) ViewAlignmentNames),
254 MakeInlet("autoresizing-mask", InletTypeEnum, &self->autoresizingMask, (ident) ViewAutoresizingNames),
255 MakeInlet("background-color", InletTypeColor, &self->backgroundColor, NULL),
256 MakeInlet("border-color", InletTypeColor, &self->borderColor, NULL),
257 MakeInlet("border-width", InletTypeInteger, &self->borderWidth, NULL),
258 MakeInlet("clips-subviews", InletTypeBool, &self->clipsSubviews, NULL),
259 MakeInlet("frame", InletTypeRectangle, &self->frame, NULL),
260 MakeInlet("hidden", InletTypeBool, &self->hidden, NULL),
261 MakeInlet("height", InletTypeInteger, &self->frame.h, NULL),
262 MakeInlet("left", InletTypeInteger, &self->frame.x, NULL),
263 MakeInlet("max-height", InletTypeInteger, &self->maxSize.h, NULL),
264 MakeInlet("max-size", InletTypeSize, &self->maxSize, NULL),
265 MakeInlet("max-width", InletTypeInteger, &self->maxSize.w, NULL),
266 MakeInlet("min-height", InletTypeInteger, &self->minSize.h, NULL),
267 MakeInlet("min-size", InletTypeSize, &self->minSize, NULL),
268 MakeInlet("min-width", InletTypeInteger, &self->minSize.w, NULL),
269 MakeInlet("padding", InletTypeRectangle, &self->padding, NULL),
270 MakeInlet("padding-top", InletTypeInteger, &self->padding.top, NULL),
271 MakeInlet("padding-right", InletTypeInteger, &self->padding.right, NULL),
272 MakeInlet("padding-bottom", InletTypeInteger, &self->padding.bottom, NULL),
273 MakeInlet("padding-left", InletTypeInteger, &self->padding.left, NULL),
274 MakeInlet("top", InletTypeInteger, &self->frame.y, NULL),
275 MakeInlet("width", InletTypeInteger, &self->frame.w, NULL)
276 );
277
278 $(self, bind, inlets, style->attributes);
279}
@ InletTypeEnum
Definition View+JSON.h:75
@ InletTypeBool
Definition View+JSON.h:46
@ InletTypeInteger
Definition View+JSON.h:95
@ InletTypeColor
Definition View+JSON.h:62
@ InletTypeSize
Definition View+JSON.h:110
@ InletTypeRectangle
Definition View+JSON.h:105
#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
const EnumName ViewAlignmentNames[]
Definition View.c:39
const EnumName ViewAutoresizingNames[]
Definition View.c:59
Inlets enable inbound data binding of View attributes through JSON.
Definition View+JSON.h:155
Dictionary * attributes
Definition Style.h:59
bool clipsSubviews
If true, subviews will be clipped to this View's frame.
Definition View.h:181
ViewAlignment alignment
The alignment.
Definition View.h:150
SDL_Color borderColor
The border color.
Definition View.h:165
int autoresizingMask
The ViewAutoresizing bitmask.
Definition View.h:155
ViewPadding padding
The padding.
Definition View.h:234
int borderWidth
The border width.
Definition View.h:170
SDL_Size minSize
The minimum size this View may be resized to during layout.
Definition View.h:212
SDL_Size maxSize
The maximum size this View may be resized to during layout.
Definition View.h:207
SDL_Color backgroundColor
The background color.
Definition View.h:160
SDL_Rect frame
The frame, relative to the superview.
Definition View.h:191
bool hidden
If true, this View is not drawn.
Definition View.h:196
int top
Definition View.h:101
int bottom
Definition View.h:101
int right
Definition View.h:101
int left
Definition View.h:101

◆ applyTheme()

static void applyTheme ( View self,
const Theme theme 
)
static

Definition at line 285 of file View.c.

285 {
286
287 assert(theme);
288
289 Style *computedStyle = $(theme, computeStyle, self);
290 assert(computedStyle);
291
292 if (!$(self->computedStyle, isComputedEqual, computedStyle)) {
293
294 release(self->computedStyle);
295 self->computedStyle = retain(computedStyle);
296
298 $(self, applyStyle, self->computedStyle);
299 }
300
301 release(computedStyle);
302}
static bool isComputedEqual(const Style *self, const Style *other)
Definition Style.c:331
static void addAttributes(Style *self, const Dictionary *attributes)
Definition Style.c:119
static Theme * theme(SDL_Window *window)
Definition Theme.c:143
static Style * computeStyle(const Theme *self, const View *view)
Definition Theme.c:103
static void applyStyle(View *self, const Style *style)
Definition View.c:248
The Style type.
Definition Style.h:43
Style * style
The element-level Style of this View.
Definition View.h:241
Style * computedStyle
The computed Style of this View.
Definition View.h:186

◆ applyThemeIfNeeded()

static void applyThemeIfNeeded ( View self,
const Theme theme 
)
static

Definition at line 317 of file View.c.

317 {
318
319 assert(theme);
320
322
323 if (self->needsApplyTheme) {
324
326
327 $(self, applyTheme, theme);
328
329 self->needsApplyTheme = false;
330 }
331}
static void clearWarnings(const View *self, WarningType type)
Definition View.c:538
static void enumerateSubviews(const View *self, ViewEnumerator enumerator, ident data)
Definition View.c:835
static void applyTheme(View *self, const Theme *theme)
Definition View.c:285
static void _applyThemeIfNeeded(View *view, ident data)
ViewEnumerator adapter for applyThemeIfNeeded.
Definition View.c:313
@ WarningTypeStyle
Definition Warning.h:34

◆ attachStylesheet()

static void attachStylesheet ( View self,
SDL_Window *  window 
)
static

Definition at line 337 of file View.c.

337 {
338
339 assert(window);
340
341 if (self->stylesheet) {
342 Theme *theme = $$(Theme, theme, window);
343 if (theme) {
344 $(theme, addStylesheet, self->stylesheet);
345 }
346 }
347}
static void addStylesheet(Theme *self, Stylesheet *stylesheet)
Definition Theme.c:55
Stylesheet * stylesheet
An optional Stylesheet.
Definition View.h:248

◆ awakeWithCharacters()

static void awakeWithCharacters ( View self,
const char *  chars 
)
static

Definition at line 353 of file View.c.

353 {
354
355 Data *data = $$(Data, dataWithConstMemory, (uint8_t *) chars, strlen(chars));
356
357 $(self, awakeWithData, data);
358
359 release(data);
360}
static void awakeWithData(View *self, const Data *data)
Definition View.c:366

◆ awakeWithData()

static void awakeWithData ( View self,
const Data *  data 
)
static

Definition at line 366 of file View.c.

366 {
367
368 JSONContext *ctx = $(alloc(JSONContext), init);
369 Dictionary *dictionary = $(ctx, objectFromData, data, 0);
370
371 if (dictionary) {
372 $(self, awakeWithDictionary, dictionary);
373 release(dictionary);
374 } else {
375 MVC_LogError("Failed to parse JSON for %s\n", classnameof(self));
376 }
377
378 release(ctx);
379}
#define MVC_LogError(fmt,...)
Definition Log.h:57
static View * init(View *self)
Definition View.c:970
static void awakeWithDictionary(View *self, const Dictionary *dictionary)
Definition View.c:385

◆ awakeWithDictionary()

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

Definition at line 385 of file View.c.

385 {
386
387 assert(dictionary);
388
389 const Inlet inlets[] = MakeInlets(
390 MakeInlet("identifier", InletTypeCharacters, &self->identifier, NULL),
391 MakeInlet("classNames", InletTypeClassNames, &self, NULL),
392 MakeInlet("style", InletTypeStyle, &self, NULL),
393 MakeInlet("subviews", InletTypeSubviews, &self, NULL)
394 );
395
396 $(self, bind, inlets, dictionary);
397}
@ InletTypeSubviews
Definition View+JSON.h:122
@ InletTypeStyle
Definition View+JSON.h:116
@ InletTypeCharacters
Definition View+JSON.h:52
@ InletTypeClassNames
Definition View+JSON.h:57

◆ awakeWithResource()

static void awakeWithResource ( View self,
const Resource *  resource 
)
static

Definition at line 403 of file View.c.

403 {
404
405 assert(resource);
406
407 $(self, awakeWithData, resource->data);
408}

◆ awakeWithResourceName()

static void awakeWithResourceName ( View self,
const char *  name 
)
static

Definition at line 414 of file View.c.

414 {
415
416 Resource *resource = $$(Resource, resourceWithName, name);
417
418 $(self, awakeWithResource, resource);
419
420 release(resource);
421}
static void awakeWithResource(View *self, const Resource *resource)
Definition View.c:403

◆ becomeKeyResponder()

static void becomeKeyResponder ( View self)
static

Definition at line 427 of file View.c.

427 {
428
429 assert(self->window);
430
431 if (!$(self, isKeyResponder)) {
432 SDL_PropertiesID props = SDL_GetWindowProperties(self->window);
433
434 View *keyResponder = SDL_GetPointerProperty(props, "keyResponder", NULL);
435 if (keyResponder) {
437 }
438
439 String *path = $(self, path);
440 MVC_LogDebug("%s\n", path->chars);
441 release(path);
442
443 SDL_SetPointerProperty(props, "keyResponder", self);
444 }
445}
#define MVC_LogDebug(fmt,...)
Definition Log.h:48
static String * path(const View *self)
Definition View.c:1266
static void resignKeyResponder(View *self)
Definition View.c:1484
static bool isKeyResponder(const View *self)
Definition View.c:1056
static View * keyResponder(const WindowController *self)

◆ becomeTouchResponder()

static void becomeTouchResponder ( View self)
static

Definition at line 451 of file View.c.

451 {
452
453 assert(self->window);
454
455 if (!$(self, isTouchResponder)) {
456 SDL_PropertiesID props = SDL_GetWindowProperties(self->window);
457
458 View *touchResponder = SDL_GetPointerProperty(props, "touchResponder", NULL);
459 if (touchResponder) {
461 }
462
463 String *path = $(self, path);
464 MVC_LogDebug("%s\n", path->chars);
465 release(path);
466
467 SDL_SetPointerProperty(props, "touchResponder", self);
468 }
469}
static bool isTouchResponder(const View *self)
Definition View.c:1069
static void resignTouchResponder(View *self)
Definition View.c:1500
static View * touchResponder(const WindowController *self)

◆ bounds()

static SDL_Rect bounds ( const View self)
static

Definition at line 492 of file View.c.

492 {
493
494 const SDL_Size size = $(self, size);
495
496 const SDL_Rect bounds = {
497 .x = self->padding.left,
498 .y = self->padding.top,
499 .w = max(0, size.w - (self->padding.left + self->padding.right)),
500 .h = max(0, size.h - (self->padding.top + self->padding.bottom)),
501 };
502
503 return bounds;
504}
static SDL_Size size(const View *self)
Definition View.c:1640
static SDL_Rect bounds(const View *self)
Definition View.c:492

◆ bringSubviewToFront()

static void bringSubviewToFront ( View self,
View subview 
)
static

Definition at line 510 of file View.c.

510 {
511
512 assert(subview);
513
514 if (subview->superview == self) {
515
516 View *last = $((Array *) self->subviews, lastObject);
517 if (last != subview) {
518 $(self, addSubviewRelativeTo, subview, last, ViewPositionAfter);
519 }
520 }
521}

◆ clearWarnings()

static void clearWarnings ( const View self,
WarningType  type 
)
static

Definition at line 538 of file View.c.

538 {
539 $(self->warnings, filter, clearWarnings_predicate, &type);
540}
static bool clearWarnings_predicate(const ident obj, ident data)
Filter Predicate for clearWarnings.
Definition View.c:526
Array * warnings
The Warnings this View generated.
Definition View.h:271

◆ clearWarnings_predicate()

static bool clearWarnings_predicate ( const ident  obj,
ident  data 
)
static

Filter Predicate for clearWarnings.

Definition at line 526 of file View.c.

526 {
527
528 const Warning *warning = obj;
529 const WarningType type = *(WarningType *) data;
530
531 return (warning->type & type) == 0;
532}
WarningType
Warning types.
Definition Warning.h:33
The Warning type.
Definition Warning.h:50
WarningType type
The WarningType.
Definition Warning.h:66

◆ clippingFrame()

static SDL_Rect clippingFrame ( const View self)
static

Definition at line 546 of file View.c.

546 {
547
548 SDL_Rect frame = $(self, renderFrame);
549
550 if (self->borderWidth && self->borderColor.a) {
551 for (int i = 0; i < self->borderWidth; i++) {
552 frame.x -= 1;
553 frame.y -= 1;
554 frame.w += 2;
555 frame.h += 2;
556 }
557 }
558
559 const View *superview = self->superview;
560 while (superview) {
561 if (superview->clipsSubviews) {
562 const SDL_Rect clippingFrame = $(superview, clippingFrame);
563 if (SDL_GetRectIntersection(&clippingFrame, &frame, &frame) == false) {
564 frame.w = frame.h = 0;
565 break;
566 }
567 }
568 superview = superview->superview;
569 }
570
571 return frame;
572}
static SDL_Rect renderFrame(const View *self)
Definition View.c:1444
static SDL_Rect clippingFrame(const View *self)
Definition View.c:546

◆ containsPoint()

static bool containsPoint ( const View self,
const SDL_Point *  point 
)
static

Definition at line 578 of file View.c.

578 {
579
580 const SDL_Rect frame = $(self, clippingFrame);
581
582 return (bool) SDL_PointInRect(point, &frame);
583}

◆ dealloc()

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

Definition at line 94 of file View.c.

94 {
95
96 View *this = (View *) self;
97
98 SDL_FilterEvents(filterViewEvents, this);
99
100 $(this, moveToWindow, NULL);
101
102 $(this, enumerateSubviews, nullifySuperview, NULL);
103
104 free(this->identifier);
105
106 release(this->classNames);
107 release(this->computedStyle);
108 release(this->style);
109 release(this->stylesheet);
110 release(this->subviews);
111 release(this->warnings);
112
113 this->superview = NULL;
114
115 super(Object, self, dealloc);
116}
static bool filterViewEvents(void *data, SDL_Event *event)
Definition View.c:75
static void nullifySuperview(View *subview, ident data)
ViewEnumerator to null out superview pointers during parent dealloc.
Definition View.c:87
static void dealloc(Object *self)
Definition View.c:94

◆ depth()

static int depth ( const View self)
static

Definition at line 589 of file View.c.

589 {
590 return (self->superview ? $(self->superview, depth) + 1 : 0);
591}
static int depth(const View *self)
Definition View.c:589

◆ descendantWithIdentifier()

static View * descendantWithIdentifier ( const View self,
const char *  identifier 
)
static

Definition at line 597 of file View.c.

597 {
598
599 assert(identifier);
600
601 if (self->identifier) {
602 if (strcmp(identifier, self->identifier) == 0) {
603 return (View *) self;
604 }
605 }
606
607 const Array *subviews = (Array *) self->subviews;
608 for (size_t i = 0; i < subviews->count; i++) {
609
610 const View *subview = subviews->elements[i];
611 View *descendant = $(subview, descendantWithIdentifier, identifier);
612 if (descendant) {
613 return descendant;
614 }
615 }
616
617 return NULL;
618}
static View * descendantWithIdentifier(const View *self, const char *identifier)
Definition View.c:597

◆ description()

static String * description ( const Object *  self)
static
See also
Object::description(const Object *)

Definition at line 121 of file View.c.

121 {
122
123 View *this = (View *) self;
124 const SDL_Rect bounds = $(this, bounds);
125
126 String *classNames = $((Object *) this->classNames, description);
127 String *description = str("%s@%p %s [%d, %d, %d, %d]",
128 this->identifier ?: classnameof(self),
129 self,
130 classNames->chars,
131 bounds.x, bounds.y, bounds.w, bounds.h);
132
133 release(classNames);
134 return description;
135}
static String * description(const Object *self)
Definition View.c:121

◆ detachStylesheet()

static void detachStylesheet ( View self,
SDL_Window *  window 
)
static

Definition at line 624 of file View.c.

624 {
625
626 assert(window);
627
628 if (self->stylesheet) {
629 Theme *theme = $$(Theme, theme, window);
630 if (theme) {
632 }
633 }
634}
static void removeStylesheet(Theme *self, Stylesheet *stylesheet)
Definition Theme.c:135

◆ didMoveToWindow()

static void didMoveToWindow ( View self,
SDL_Window *  window 
)
static

Definition at line 640 of file View.c.

640 {
641
642 if (window) {
643 $(self, attachStylesheet, window);
644
645 if (self->superview == NULL) {
646 $(self, sizeToFill);
647 }
648
649 self->needsLayout = true;
650 }
651}
static void sizeToFill(View *self)
Definition View.c:1745
static void attachStylesheet(View *self, SDL_Window *window)
Definition View.c:337

◆ didReceiveEvent()

static bool didReceiveEvent ( const View self,
const SDL_Event *  event 
)
static

Definition at line 657 of file View.c.

657 {
658
659 if ($(self, isKeyResponder)) {
660 switch (event->type) {
661 case SDL_EVENT_KEY_DOWN:
662 case SDL_EVENT_KEY_UP:
663 case SDL_EVENT_TEXT_INPUT:
664 return true;
665 }
666 }
667
668 if ($(self, isVisible)) {
669
670 SDL_Point point;
671
672 switch (event->type) {
673 case SDL_EVENT_MOUSE_BUTTON_DOWN:
674 case SDL_EVENT_MOUSE_BUTTON_UP:
675 point = MakePoint(event->button.x, event->button.y);
676 break;
677 case SDL_EVENT_MOUSE_MOTION:
678 point = MakePoint(event->motion.x, event->motion.y);
679 break;
680 case SDL_EVENT_MOUSE_WHEEL: {
681 float mx, my;
682 SDL_GetMouseState(&mx, &my);
683 point = MakePoint(mx, my);
684 break;
685 }
686 default:
687 return false;
688 }
689
690 return $(self, containsPoint, &point);
691 }
692
693 return false;
694}
static bool isVisible(const View *self)
Definition View.c:1082
static bool containsPoint(const View *self, const SDL_Point *point)
Definition View.c:578

◆ draw()

static void draw ( View self,
Renderer renderer 
)
static

Definition at line 709 of file View.c.

709 {
710
711 assert(self->window);
712
713 if (self->hidden == false) {
714
715 $(renderer, drawView, self);
716
717 $(self, enumerateSubviews, _draw, renderer);
718 }
719}
static void drawView(Renderer *self, View *view)
Definition Renderer.c:246
static void _draw(View *view, ident data)
ViewEnumerator adapter for draw.
Definition View.c:705

◆ emitViewEvent()

static void emitViewEvent ( View self,
ViewEvent  code,
ident  data 
)
static

Definition at line 725 of file View.c.

725 {
726 SDL_PushEvent((SDL_Event *) &(const SDL_UserEvent) {
727 .type = MVC_VIEW_EVENT,
728 .code = code,
729 .data1 = self,
730 .data2 = data
731 });
732}
Uint32 MVC_VIEW_EVENT
Definition View.c:37

◆ enumerate()

static void enumerate ( View self,
ViewEnumerator  enumerator,
ident  data 
)
static

Definition at line 738 of file View.c.

738 {
739
740 assert(enumerator);
741
742 enumerator(self, data);
743
744 $(self, enumerateDescendants, enumerator, data);
745}
static void enumerateDescendants(const View *self, ViewEnumerator enumerator, ident data)
Definition View.c:797

◆ enumerateAdjacent()

static void enumerateAdjacent ( const View self,
ViewEnumerator  enumerator,
ident  data 
)
static

Definition at line 751 of file View.c.

751 {
752
753 assert(enumerator);
754
755 if (self->superview) {
756 const Array *siblings = (Array *) self->superview->subviews;
757 const ssize_t index = $(siblings, indexOfObject, (const ident) self);
758 if (index > 0) {
759 enumerator($(siblings, objectAtIndex, index - 1), data);
760 }
761 if (index < (ssize_t) (siblings->count - 1)) {
762 enumerator($(siblings, objectAtIndex, index + 1), data);
763 }
764 }
765}

◆ enumerateAncestors()

static void enumerateAncestors ( const View self,
ViewEnumerator  enumerator,
ident  data 
)
static

Definition at line 771 of file View.c.

771 {
772
773 assert(enumerator);
774
775 for (View *view = self->superview; view; view = view->superview) {
776 enumerator(view, data);
777 }
778}

◆ enumerateDescendants()

static void enumerateDescendants ( const View self,
ViewEnumerator  enumerator,
ident  data 
)
static

Definition at line 797 of file View.c.

797 {
798
799 assert(enumerator);
800
801 const Array *subviews = (Array *) self->subviews;
802 for (size_t i = 0; i < subviews->count; i++) {
803
804 View *subview = subviews->elements[i];
805 enumerator(subview, data);
806
807 $(subview, enumerateDescendants, enumerator, data);
808 }
809}

◆ enumerateSelection()

static void enumerateSelection ( View self,
const char *  rule,
ViewEnumerator  enumerator,
ident  data 
)
static

Definition at line 784 of file View.c.

784 {
785
786 Selector *selector = $(alloc(Selector), initWithRule, rule);
787 assert(selector);
788
789 $(selector, enumerateSelection, self, enumerator, data);
790 release(selector);
791}
static void enumerateSelection(View *self, const char *rule, ViewEnumerator enumerator, ident data)
Definition View.c:784

◆ enumerateSiblings()

static void enumerateSiblings ( const View self,
ViewEnumerator  enumerator,
ident  data 
)
static

Definition at line 815 of file View.c.

815 {
816
817 assert(enumerator);
818
819 if (self->superview) {
820
821 const Array *siblings = (Array *) self->superview->subviews;
822 for (size_t i = 0; i < siblings->count; i++) {
823 View *sibling = siblings->elements[i];
824 if (sibling != self) {
825 enumerator(sibling, data);
826 }
827 }
828 }
829}

◆ enumerateSubviews()

static void enumerateSubviews ( const View self,
ViewEnumerator  enumerator,
ident  data 
)
static

Definition at line 835 of file View.c.

835 {
836
837 assert(enumerator);
838
839 const Array *subviews = (Array *) self->subviews;
840 for (size_t i = 0; i < subviews->count; i++) {
841 enumerator((View *) subviews->elements[i], data);
842 }
843}

◆ enumerateSuperview()

static void enumerateSuperview ( const View self,
ViewEnumerator  enumerator,
ident  data 
)
static

Definition at line 849 of file View.c.

849 {
850
851 assert(enumerator);
852
853 if (self->superview) {
854 enumerator(self->superview, data);
855 }
856}

◆ enumerateVisible()

static void enumerateVisible ( View self,
ViewEnumerator  enumerator,
ident  data 
)
static

Definition at line 862 of file View.c.

862 {
863
864 if ($(self, isVisible) == false) {
865 return;
866 }
867
868 enumerator(self, data);
869
870 const Array *subviews = (Array *) self->subviews;
871 for (size_t i = 0; i < subviews->count; i++) {
872
873 View *subview = subviews->elements[i];
874 $(subview, enumerateVisible, enumerator, data);
875 }
876}
static void enumerateVisible(View *self, ViewEnumerator enumerator, ident data)
Definition View.c:862

◆ filterViewEvents()

static bool filterViewEvents ( void *  data,
SDL_Event *  event 
)
static

SDL_EventFilter to purge any MVC_VIEW_EVENTs for this View.

Definition at line 75 of file View.c.

75 {
76
77 if (event->type == MVC_VIEW_EVENT && event->user.data1 == data) {
78 return false;
79 }
80
81 return true;
82}

◆ hasClassName()

static bool hasClassName ( const View self,
const char *  className 
)
static

Definition at line 889 of file View.c.

889 {
890
891 if (className) {
892 return $((Set *) self->classNames, containsObjectMatching, hasClassName_predicate, (ident) className);
893 }
894
895 return false;
896}
static bool hasClassName_predicate(const ident obj, ident data)
Predicate for hasClassName.
Definition View.c:881

◆ hasClassName_predicate()

static bool hasClassName_predicate ( const ident  obj,
ident  data 
)
static

Predicate for hasClassName.

Definition at line 881 of file View.c.

881 {
882 return strcmp(((String *) obj)->chars, (const char *) data) == 0;
883}

◆ hasOverflow()

static bool hasOverflow ( const View self)
static

Definition at line 928 of file View.c.

928 {
929
930 Overflow overflow = {
931 .bounds = $(self, bounds)
932 };
933
934 $(self, enumerateSubviews, hasOverflow_enumerate, (ident) &overflow);
935
936 return overflow.hasOverflow;
937}
static void hasOverflow_enumerate(View *view, ident data)
ViewEnumerator for hasOverflow.
Definition View.c:906
SDL_Rect bounds
Definition View.c:899
bool hasOverflow
Definition View.c:900

◆ hasOverflow_enumerate()

static void hasOverflow_enumerate ( View view,
ident  data 
)
static

ViewEnumerator for hasOverflow.

Definition at line 906 of file View.c.

906 {
907
908 Overflow *overflow = data;
909
910 if (!view->hidden) {
911
912 const SDL_Rect bounds = $(view, bounds);
913
914 if (bounds.x + bounds.w > overflow->bounds.w || bounds.y + bounds.h > overflow->bounds.h) {
915
916 overflow->hasOverflow = true;
917
918 $(view, warn, WarningTypeLayout, "Exceeds superview bounds [%d %d %d %d]",
919 overflow->bounds.x, overflow->bounds.y, overflow->bounds.w, overflow->bounds.h);
920 }
921 }
922}
static void warn(View *self, WarningType type, const char *fmt,...)
Definition View.c:1913
@ WarningTypeLayout
Definition Warning.h:35

◆ hitTest()

static View * hitTest ( const View self,
const SDL_Point *  point 
)
static

Definition at line 943 of file View.c.

943 {
944
945 if (self->hidden == false) {
946
947 if ($(self, containsPoint, point)) {
948
949 const Array *subviews = (Array *) self->subviews;
950 for (size_t i = subviews->count; i; i--) {
951
952 const View *subview = subviews->elements[i - 1];
953 const View *view = $(subview, hitTest, point);
954 if (view) {
955 return (View *) view;
956 }
957 }
958
959 return (View *) self;
960 }
961 }
962
963 return NULL;
964}
static View * hitTest(const View *self, const SDL_Point *point)
Definition View.c:943

◆ init()

static View * init ( View self)
static

Definition at line 970 of file View.c.

970 {
971 return $(self, initWithFrame, NULL);
972}
static View * initWithFrame(View *self, const SDL_Rect *frame)
Definition View.c:978

◆ initialize()

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

Definition at line 1949 of file View.c.

1949 {
1950
1951 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
1952 ((ObjectInterface *) clazz->interface)->description = description;
1953
1954 ((ViewInterface *) clazz->interface)->acceptsKeyResponder = acceptsKeyResponder;
1955 ((ViewInterface *) clazz->interface)->acceptsTouchResponder = acceptsTouchResponder;
1956 ((ViewInterface *) clazz->interface)->addClassName = addClassName;
1957 ((ViewInterface *) clazz->interface)->addSubview = addSubview;
1958 ((ViewInterface *) clazz->interface)->addSubviewRelativeTo = addSubviewRelativeTo;
1959 ((ViewInterface *) clazz->interface)->ancestorWithIdentifier = ancestorWithIdentifier;
1960 ((ViewInterface *) clazz->interface)->applyStyle = applyStyle;
1961 ((ViewInterface *) clazz->interface)->applyTheme = applyTheme;
1962 ((ViewInterface *) clazz->interface)->applyThemeIfNeeded = applyThemeIfNeeded;
1963 ((ViewInterface *) clazz->interface)->attachStylesheet = attachStylesheet;
1964 ((ViewInterface *) clazz->interface)->awakeWithCharacters = awakeWithCharacters;
1965 ((ViewInterface *) clazz->interface)->awakeWithData = awakeWithData;
1966 ((ViewInterface *) clazz->interface)->awakeWithDictionary = awakeWithDictionary;
1967 ((ViewInterface *) clazz->interface)->awakeWithResource = awakeWithResource;
1968 ((ViewInterface *) clazz->interface)->awakeWithResourceName = awakeWithResourceName;
1969 ((ViewInterface *) clazz->interface)->becomeKeyResponder = becomeKeyResponder;
1970 ((ViewInterface *) clazz->interface)->becomeTouchResponder = becomeTouchResponder;
1971 ((ViewInterface *) clazz->interface)->bind = _bind;
1972 ((ViewInterface *) clazz->interface)->bounds = bounds;
1973 ((ViewInterface *) clazz->interface)->bringSubviewToFront = bringSubviewToFront;
1974 ((ViewInterface *) clazz->interface)->clearWarnings = clearWarnings;
1975 ((ViewInterface *) clazz->interface)->clippingFrame = clippingFrame;
1976 ((ViewInterface *) clazz->interface)->containsPoint = containsPoint;
1977 ((ViewInterface *) clazz->interface)->depth = depth;
1978 ((ViewInterface *) clazz->interface)->descendantWithIdentifier = descendantWithIdentifier;
1979 ((ViewInterface *) clazz->interface)->detachStylesheet = detachStylesheet;
1980 ((ViewInterface *) clazz->interface)->didMoveToWindow = didMoveToWindow;
1981 ((ViewInterface *) clazz->interface)->didReceiveEvent = didReceiveEvent;
1982 ((ViewInterface *) clazz->interface)->draw = draw;
1983 ((ViewInterface *) clazz->interface)->emitViewEvent = emitViewEvent;
1984 ((ViewInterface *) clazz->interface)->enumerate = enumerate;
1985 ((ViewInterface *) clazz->interface)->enumerateAdjacent = enumerateAdjacent;
1986 ((ViewInterface *) clazz->interface)->enumerateAncestors = enumerateAncestors;
1987 ((ViewInterface *) clazz->interface)->enumerateDescendants = enumerateDescendants;
1988 ((ViewInterface *) clazz->interface)->enumerateSelection = enumerateSelection;
1989 ((ViewInterface *) clazz->interface)->enumerateSiblings = enumerateSiblings;
1990 ((ViewInterface *) clazz->interface)->enumerateSubviews = enumerateSubviews;
1991 ((ViewInterface *) clazz->interface)->enumerateSuperview = enumerateSuperview;
1992 ((ViewInterface *) clazz->interface)->enumerateVisible = enumerateVisible;
1993 ((ViewInterface *) clazz->interface)->hasClassName = hasClassName;
1994 ((ViewInterface *) clazz->interface)->hasOverflow = hasOverflow;
1995 ((ViewInterface *) clazz->interface)->hitTest = hitTest;
1996 ((ViewInterface *) clazz->interface)->init = init;
1997 ((ViewInterface *) clazz->interface)->initWithFrame = initWithFrame;
1998 ((ViewInterface *) clazz->interface)->invalidateStyle = invalidateStyle;
1999 ((ViewInterface *) clazz->interface)->isContainer = isContainer;
2000 ((ViewInterface *) clazz->interface)->isDescendantOfView = isDescendantOfView;
2001 ((ViewInterface *) clazz->interface)->isKeyResponder = isKeyResponder;
2002 ((ViewInterface *) clazz->interface)->isTouchResponder = isTouchResponder;
2003 ((ViewInterface *) clazz->interface)->isVisible = isVisible;
2004 ((ViewInterface *) clazz->interface)->layoutIfNeeded = layoutIfNeeded;
2005 ((ViewInterface *) clazz->interface)->layoutSubviews = layoutSubviews;
2006 ((ViewInterface *) clazz->interface)->matchesSelector = matchesSelector;
2007 ((ViewInterface *) clazz->interface)->moveToWindow = moveToWindow;
2008 ((ViewInterface *) clazz->interface)->path = path;
2009 ((ViewInterface *) clazz->interface)->removeAllClassNames = removeAllClassNames;
2010 ((ViewInterface *) clazz->interface)->removeAllSubviews = removeAllSubviews;
2011 ((ViewInterface *) clazz->interface)->removeClassName = removeClassName;
2012 ((ViewInterface *) clazz->interface)->removeFromSuperview = removeFromSuperview;
2013 ((ViewInterface *) clazz->interface)->removeSubview = removeSubview;
2014 ((ViewInterface *) clazz->interface)->render = render;
2015 ((ViewInterface *) clazz->interface)->renderDeviceDidReset = renderDeviceDidReset;
2016 ((ViewInterface *) clazz->interface)->renderDeviceWillReset = renderDeviceWillReset;
2017 ((ViewInterface *) clazz->interface)->renderFrame = renderFrame;
2018 ((ViewInterface *) clazz->interface)->replaceSubview = replaceSubview;
2019 ((ViewInterface *) clazz->interface)->resignKeyResponder = resignKeyResponder;
2020 ((ViewInterface *) clazz->interface)->resignTouchResponder = resignTouchResponder;
2021 ((ViewInterface *) clazz->interface)->resize = resize;
2022 ((ViewInterface *) clazz->interface)->resolve = resolve;
2023 ((ViewInterface *) clazz->interface)->respondToEvent = respondToEvent;
2024 ((ViewInterface *) clazz->interface)->select = _select;
2025 ((ViewInterface *) clazz->interface)->selectFirst = selectFirst;
2026 ((ViewInterface *) clazz->interface)->size = size;
2027 ((ViewInterface *) clazz->interface)->sizeThatContains = sizeThatContains;
2028 ((ViewInterface *) clazz->interface)->sizeThatFills = sizeThatFills;
2029 ((ViewInterface *) clazz->interface)->sizeThatFits = sizeThatFits;
2030 ((ViewInterface *) clazz->interface)->sizeToContain = sizeToContain;
2031 ((ViewInterface *) clazz->interface)->sizeToFill = sizeToFill;
2032 ((ViewInterface *) clazz->interface)->sizeToFit = sizeToFit;
2033 ((ViewInterface *) clazz->interface)->subviewWithIdentifier = subviewWithIdentifier;
2034 ((ViewInterface *) clazz->interface)->updateBindings = updateBindings;
2035 ((ViewInterface *) clazz->interface)->viewport = viewport;
2036 ((ViewInterface *) clazz->interface)->viewWithCharacters = viewWithCharacters;
2037 ((ViewInterface *) clazz->interface)->viewWithData = viewWithData;
2038 ((ViewInterface *) clazz->interface)->viewWithDictionary = viewWithDictionary;
2039 ((ViewInterface *) clazz->interface)->viewWithResource = viewWithResource;
2040 ((ViewInterface *) clazz->interface)->viewWithResourceName = viewWithResourceName;
2041 ((ViewInterface *) clazz->interface)->visibleSubviews = visibleSubviews;
2042 ((ViewInterface *) clazz->interface)->warn = warn;
2043 ((ViewInterface *) clazz->interface)->willMoveToWindow = willMoveToWindow;
2044
2045 MVC_NOTIFICATION_EVENT = SDL_RegisterEvents(1);
2046 assert(MVC_NOTIFICATION_EVENT != 0);
2047
2048 MVC_VIEW_EVENT = SDL_RegisterEvents(1);
2049 assert(MVC_VIEW_EVENT != 0);
2050}
static View * viewWithResource(const Resource *resource, Outlet *outlets)
Definition View.c:1869
static void removeClassName(View *self, const char *className)
Definition View.c:1333
static void addClassName(View *self, const char *className)
Definition View.c:159
static View * selectFirst(View *self, const char *rule)
Definition View.c:1625
static bool isContainer(const View *self)
Definition View.c:1030
static void didMoveToWindow(View *self, SDL_Window *window)
Definition View.c:640
static bool isDescendantOfView(const View *self, const View *view)
Definition View.c:1038
static void becomeKeyResponder(View *self)
Definition View.c:427
static void resize(View *self, const SDL_Size *size)
Definition View.c:1516
static void detachStylesheet(View *self, SDL_Window *window)
Definition View.c:624
static void layoutIfNeeded(View *self)
Definition View.c:1104
static void sizeToContain(View *self)
Definition View.c:1734
static bool acceptsKeyResponder(const View *self)
Definition View.c:143
static Set * _select(View *self, const char *rule)
Definition View.c:1610
static void enumerateAncestors(const View *self, ViewEnumerator enumerator, ident data)
Definition View.c:771
static SDL_Size sizeThatFills(const View *self)
Definition View.c:1660
static void removeAllClassNames(View *self)
Definition View.c:1307
static void removeSubview(View *self, View *subview)
Definition View.c:1361
static View * viewWithResourceName(const char *name, Outlet *outlets)
Definition View.c:1880
static void becomeTouchResponder(View *self)
Definition View.c:451
static void respondToEvent(View *self, const SDL_Event *event)
Definition View.c:1558
static void replaceSubview(View *self, View *subview, View *replacement)
Definition View.c:1471
static bool matchesSelector(const View *self, const SimpleSelector *simpleSelector)
Definition View.c:1180
static SDL_Size sizeThatFits(const View *self)
Definition View.c:1676
static void bringSubviewToFront(View *self, View *subview)
Definition View.c:510
static bool didReceiveEvent(const View *self, const SDL_Event *event)
Definition View.c:657
static View * subviewWithIdentifier(const View *self, const char *identifier)
Definition View.c:1767
static bool hasOverflow(const View *self)
Definition View.c:928
static Array * visibleSubviews(const View *self)
Definition View.c:1905
static void awakeWithCharacters(View *self, const char *chars)
Definition View.c:353
static void removeAllSubviews(View *self)
Definition View.c:1325
static SDL_Size sizeThatContains(const View *self)
Definition View.c:1648
static void render(View *self, Renderer *renderer)
Definition View.c:1381
static void awakeWithResourceName(View *self, const char *name)
Definition View.c:414
static void addSubview(View *self, View *subview)
Definition View.c:177
static View * viewWithData(const Data *data, Outlet *outlets)
Definition View.c:1833
static View * viewWithCharacters(const char *chars, Outlet *outlets)
Definition View.c:1818
static bool acceptsTouchResponder(const View *self)
Definition View.c:151
static void renderDeviceWillReset(View *self)
Definition View.c:1436
static bool _bind(View *self, const Inlet *inlets, const Dictionary *dictionary)
Definition View.c:475
static void updateBindings(View *self)
Definition View.c:1797
static void willMoveToWindow(View *self, SDL_Window *window)
Definition View.c:1935
Uint32 MVC_NOTIFICATION_EVENT
Definition View.c:36
static void renderDeviceDidReset(View *self)
Definition View.c:1421
static void enumerateSuperview(const View *self, ViewEnumerator enumerator, ident data)
Definition View.c:849
static void layoutSubviews(View *self)
Definition View.c:1122
static void enumerate(View *self, ViewEnumerator enumerator, ident data)
Definition View.c:738
static void enumerateAdjacent(const View *self, ViewEnumerator enumerator, ident data)
Definition View.c:751
static SDL_Rect viewport(const View *self)
Definition View.c:1805
static bool hasClassName(const View *self, const char *className)
Definition View.c:889
static void sizeToFit(View *self)
Definition View.c:1756
static void enumerateSiblings(const View *self, ViewEnumerator enumerator, ident data)
Definition View.c:815
static View * viewWithDictionary(const Dictionary *dictionary, Outlet *outlets)
Definition View.c:1854
static View * ancestorWithIdentifier(const View *self, const char *identifier)
Definition View.c:227
static void resolve(View *self, Outlet *outlets)
Definition View.c:1538
static void emitViewEvent(View *self, ViewEvent code, ident data)
Definition View.c:725
void updateBindings(View *self)
Updates data bindings, prompting the appropriate layout changes.
void invalidateStyle(View *self)
Invalidates the computed Style for this View and its descendants.
Definition View.c:1022
View * viewWithResource(const Resource *resource, Outlet *outlets)
Instantiates a View initialized with the JSON data in resource.
Definition View.c:1869
Array * visibleSubviews(const View *self)
Definition PageView.c:92
View * viewWithResourceName(const char *name, Outlet *outlets)
Instantiates a View initialized with the JSON Resource with the specified name.
Definition View.c:1880
void applyStyle(View *self, const Style *style)
Applies the given Style to this View.
void detachStylesheet(View *self, SDL_Window *window)
Detaches this View's Stylesheet from the Theme associated with the given window.
Definition View.c:624
SDL_Size size(const View *self)
Definition View.c:1640
View * viewWithData(const Data *data, Outlet *outlets)
Instantiates a View initialized with the contents of data.
Definition View.c:1833
View * init(View *self)
Initializes this View.
Definition Box.c:67
View * initWithFrame(View *self, const SDL_Rect *frame)
Initializes this View with the specified frame.
Definition View.c:978
View * viewWithDictionary(const Dictionary *dictionary, Outlet *outlets)
Instantiates a View initialized with the attributes described in dictionary.
Definition View.c:1854

◆ initWithFrame()

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

Definition at line 978 of file View.c.

978 {
979
980 self = (View *) super(Object, self, init);
981 if (self) {
982
983 if (frame) {
984 self->frame = *frame;
985 }
986
987 self->classNames = $$(Set, setWithCapacity, 0);
988 assert(self->classNames);
989
990 self->computedStyle = $(alloc(Style), initWithAttributes, NULL);
991 assert(self->computedStyle);
992
993 self->subviews = $$(Array, arrayWithCapacity, 0);
994 assert(self->subviews);
995
996 self->style = $(alloc(Style), initWithAttributes, NULL);
997 assert(self->style);
998
999 self->warnings = $$(Array, arrayWithCapacity, 0);
1000 assert(self->warnings);
1001
1002 self->maxSize = MakeSize(INT32_MAX, INT32_MAX);
1003
1004 self->needsApplyTheme = true;
1005 self->needsLayout = true;
1006 }
1007
1008 return self;
1009}
static Style * initWithAttributes(Style *self, const Dictionary *attributes)
Definition Style.c:292

◆ invalidateStyle()

static void invalidateStyle ( View self)
static

Definition at line 1022 of file View.c.

1022 {
1023 $(self, enumerate, invalidateStyle_enumerate, NULL);
1024}
static void invalidateStyle_enumerate(View *view, ident data)
ViewEnumerator for invalidateStyle.
Definition View.c:1014

◆ invalidateStyle_enumerate()

static void invalidateStyle_enumerate ( View view,
ident  data 
)
static

ViewEnumerator for invalidateStyle.

Definition at line 1014 of file View.c.

1014 {
1015 view->needsApplyTheme = true;
1016}

◆ isContainer()

static bool isContainer ( const View self)
static

Definition at line 1030 of file View.c.

1030 {
1032}
@ ViewAutoresizingContain
Definition View.h:92
@ ViewAutoresizingFit
Definition View.h:91

◆ isDescendantOfView()

static bool isDescendantOfView ( const View self,
const View view 
)
static

Definition at line 1038 of file View.c.

1038 {
1039
1040 assert(view);
1041
1042 while (self) {
1043 if (self == view) {
1044 return true;
1045 }
1046 self = self->superview;
1047 }
1048
1049 return false;
1050}

◆ isKeyResponder()

static bool isKeyResponder ( const View self)
static

Definition at line 1056 of file View.c.

1056 {
1057
1058 if (self->window) {
1059 return SDL_GetPointerProperty(SDL_GetWindowProperties(self->window), "keyResponder", NULL) == self;
1060 } else {
1061 return false;
1062 }
1063}

◆ isTouchResponder()

static bool isTouchResponder ( const View self)
static

Definition at line 1069 of file View.c.

1069 {
1070
1071 if (self->window) {
1072 return SDL_GetPointerProperty(SDL_GetWindowProperties(self->window), "touchResponder", NULL) == self;
1073 } else {
1074 return false;
1075 }
1076}

◆ isVisible()

static bool isVisible ( const View self)
static

Definition at line 1082 of file View.c.

1082 {
1083
1084 for (const View *view = self; view; view = view->superview) {
1085 if (view->hidden) {
1086 return false;
1087 }
1088 }
1089
1090 return true;
1091}

◆ layoutIfNeeded()

static void layoutIfNeeded ( View self)
static

Definition at line 1104 of file View.c.

1104 {
1105
1107
1108 if (self->needsLayout) {
1109
1111
1112 $(self, layoutSubviews);
1113
1114 self->needsLayout = false;
1115 }
1116}
static void layoutIfNeeded_enumerate(View *subview, ident data)
ViewEnumerator for layoutIfNeeded recursion.
Definition View.c:1096

◆ layoutIfNeeded_enumerate()

static void layoutIfNeeded_enumerate ( View subview,
ident  data 
)
static

ViewEnumerator for layoutIfNeeded recursion.

Definition at line 1096 of file View.c.

1096 {
1097 $(subview, layoutIfNeeded);
1098}

◆ layoutSubviews()

static void layoutSubviews ( View self)
static

Definition at line 1122 of file View.c.

1122 {
1123
1125 $(self, sizeToContain);
1126 } else if (self->autoresizingMask & ViewAutoresizingFit) {
1127 $(self, sizeToFit);
1128 }
1129
1130 const SDL_Rect bounds = $(self, bounds);
1131
1132 const Array *subviews = (Array *) self->subviews;
1133 for (size_t i = 0; i < subviews->count; i++) {
1134
1135 View *subview = subviews->elements[i];
1136
1137 SDL_Size subviewSize = $(subview, size);
1138
1139 if (subview->autoresizingMask & ViewAutoresizingWidth) {
1140 subviewSize.w = bounds.w;
1141 }
1142
1144 subviewSize.h = bounds.h;
1145 }
1146
1147 $(subview, resize, &subviewSize);
1148 $(subview, layoutIfNeeded);
1149
1150 switch (subview->alignment & ViewAlignmentMaskHorizontal) {
1151 case ViewAlignmentLeft:
1152 subview->frame.x = 0;
1153 break;
1155 subview->frame.x = (bounds.w - subview->frame.w) * 0.5f;
1156 break;
1157 case ViewAlignmentRight:
1158 subview->frame.x = bounds.w - subview->frame.w;
1159 break;
1160 }
1161
1162 switch (subview->alignment & ViewAlignmentMaskVertical) {
1164 subview->frame.y = 0;
1165 break;
1167 subview->frame.y = (bounds.h - subview->frame.h) * 0.5f;
1168 break;
1170 subview->frame.y = bounds.h - subview->frame.h;
1171 break;
1172 }
1173 }
1174}
#define ViewAlignmentMaskBottom
Definition View.h:46
#define ViewAlignmentMaskTop
Definition View.h:44
#define ViewAlignmentMaskMiddle
Definition View.h:45
#define ViewAlignmentMaskHorizontal
Definition View.h:55
#define ViewAlignmentMaskVertical
Definition View.h:52
@ ViewAutoresizingWidth
Definition View.h:88
@ ViewAutoresizingHeight
Definition View.h:89
@ ViewAlignmentCenter
Definition View.h:67
@ ViewAlignmentLeft
Definition View.h:66
@ ViewAlignmentRight
Definition View.h:68

◆ matchesSelector()

static bool matchesSelector ( const View self,
const SimpleSelector simpleSelector 
)
static

Definition at line 1180 of file View.c.

1180 {
1181
1182 assert(simpleSelector);
1183
1184 const char *pattern = simpleSelector->pattern;
1185
1186 switch (simpleSelector->type) {
1188 return false;
1189
1191 return true;
1192
1194 const Class *clazz = classForName(pattern);
1195 if (clazz) {
1196 return $((Object *) self, isKindOfClass, clazz);
1197 }
1198 }
1199 break;
1200
1202 return $(self, hasClassName, pattern);
1203
1205 if (self->identifier) {
1206 return strcmp(self->identifier, pattern) == 0;
1207 } else {
1208 return false;
1209 }
1210
1212 if (strcmp("first-child", pattern) == 0) {
1213 if (self->superview) {
1214 return $((Array *) self->superview->subviews, firstObject) == self;
1215 }
1216 } else if (strcmp("last-child", pattern) == 0) {
1217 if (self->superview) {
1218 return $((Array *) self->superview->subviews, lastObject) == self;
1219 }
1220 } else if (strcmp("nth-child(even)", pattern) == 0) {
1221 if (self->superview) {
1222 return ($((Array *) self->superview->subviews, indexOfObject, (ident) self) & 1) == 0;
1223 }
1224 } else if (strcmp("nth-child(odd)", pattern) == 0) {
1225 if (self->superview) {
1226 return $((Array *) self->superview->subviews, indexOfObject, (ident) self) & 1;
1227 }
1228 } else if (strcmp("hover", pattern) == 0) {
1229 float mx, my;
1230 SDL_GetMouseState(&mx, &my);
1231 SDL_Point point = MakePoint(mx, my);
1232 return $(self, containsPoint, &point);
1233 }
1234 break;
1235 }
1236
1237 return false;
1238}
@ SimpleSelectorTypePseudo
@ SimpleSelectorTypeId
@ SimpleSelectorTypeClass
@ SimpleSelectorTypeUniversal
@ SimpleSelectorTypeType
@ SimpleSelectorTypeNone
SimpleSelectorType type
The SimpleSelectorType.
char * pattern
The pattern, as provided by the user.

◆ moveToWindow()

static void moveToWindow ( View self,
SDL_Window *  window 
)
static

Definition at line 1251 of file View.c.

1251 {
1252
1253 $(self, willMoveToWindow, window);
1254
1255 self->window = window;
1256
1257 $(self, didMoveToWindow, window);
1258
1259 $(self, enumerateSubviews, moveToWindow_enumerate, window);
1260}
static void moveToWindow_enumerate(View *subview, ident data)
ViewEnumerator for moveToWindow recursion.
Definition View.c:1243

◆ moveToWindow_enumerate()

static void moveToWindow_enumerate ( View subview,
ident  data 
)
static

ViewEnumerator for moveToWindow recursion.

Definition at line 1243 of file View.c.

1243 {
1244 $(subview, moveToWindow, data);
1245}

◆ nullifySuperview()

static void nullifySuperview ( View subview,
ident  data 
)
static

ViewEnumerator to null out superview pointers during parent dealloc.

Definition at line 87 of file View.c.

87 {
88 subview->superview = NULL;
89}

◆ path()

static String * path ( const View self)
static

Definition at line 1266 of file View.c.

1266 {
1267
1268 Array *parts = $$(Array, array);
1269
1270 const View *view = self;
1271 while (view) {
1272
1273 Array *classNames = $((Set *) view->classNames, allObjects);
1274
1275 String *part;
1276 if (view->identifier) {
1277 part = str("#%s", view->identifier);
1278 } else if (classNames->count) {
1279 part = str(".%s", ((String *) $(classNames, firstObject))->chars);
1280 } else {
1281 part = str("%s", classnameof(view));
1282 }
1283
1284 release(classNames);
1285
1286 $(parts, insertObjectAtIndex, part, 0);
1287 release(part);
1288
1289 if (view->viewController) {
1290 break;
1291 }
1292
1293 view = view->superview;
1294 }
1295
1296 String *path = $((Array *) parts, componentsJoinedByCharacters, " > ");
1297
1298 release(parts);
1299
1300 return path;
1301}
ViewController * viewController
The ViewController.
Definition View.h:265

◆ removeAllClassNames()

static void removeAllClassNames ( View self)
static

Definition at line 1307 of file View.c.

1307 {
1308
1309 $(self->classNames, removeAllObjects);
1310
1311 $(self, invalidateStyle);
1312}

◆ removeAllSubviews()

static void removeAllSubviews ( View self)
static

Definition at line 1325 of file View.c.

1325 {
1326 $(self->subviews, removeAllObjectsWithEnumerator, removeAllSubviews_enumerate, self);
1327}
static void removeAllSubviews_enumerate(const Array *array, ident obj, ident data)
ArrayEnumerator for removeAllSubviews.
Definition View.c:1317

◆ removeAllSubviews_enumerate()

static void removeAllSubviews_enumerate ( const Array *  array,
ident  obj,
ident  data 
)
static

ArrayEnumerator for removeAllSubviews.

Definition at line 1317 of file View.c.

1317 {
1318 $((View *) data, removeSubview, obj);
1319}

◆ removeClassName()

static void removeClassName ( View self,
const char *  className 
)
static

Definition at line 1333 of file View.c.

1333 {
1334
1335 if (className) {
1336 String *string = $$(String, stringWithCharacters, className);
1337 assert(string);
1338
1339 $(self->classNames, removeObject, string);
1340 release(string);
1341
1342 $(self, invalidateStyle);
1343 }
1344}

◆ removeFromSuperview()

static void removeFromSuperview ( View self)
static

Definition at line 1350 of file View.c.

1350 {
1351
1352 if (self->superview) {
1353 $(self->superview, removeSubview, self);
1354 }
1355}

◆ removeSubview()

static void removeSubview ( View self,
View subview 
)
static

Definition at line 1361 of file View.c.

1361 {
1362
1363 assert(subview);
1364
1365 if (subview->superview == self) {
1366
1367 subview->superview = NULL;
1368
1369 $(subview, moveToWindow, NULL);
1370
1371 $(self->subviews, removeObject, subview);
1372
1373 self->needsLayout = true;
1374 }
1375}

◆ render()

static void render ( View self,
Renderer renderer 
)
static

Definition at line 1381 of file View.c.

1381 {
1382
1383 assert(self->window);
1384
1385 if ($(self, hasClassName, "breakpoint")) {
1386 SDL_TriggerBreakpoint();
1387 }
1388
1389 if (self->backgroundColor.a) {
1390
1391 const SDL_Rect frame = $(self, renderFrame);
1392 $(renderer, drawRectFilled, &frame, &self->backgroundColor);
1393 }
1394
1395 if (self->borderWidth && self->borderColor.a) {
1396
1397 SDL_Rect frame = $(self, renderFrame);
1398 for (int i = 0; i < self->borderWidth; i++) {
1399
1400 $(renderer, drawRect, &frame, &self->borderColor);
1401
1402 frame.x -= 1;
1403 frame.y -= 1;
1404 frame.w += 2;
1405 frame.h += 2;
1406 }
1407 }
1408}
static void drawRectFilled(const Renderer *self, const SDL_Rect *rect, const SDL_Color *color)
Definition Renderer.c:200
static void drawRect(const Renderer *self, const SDL_Rect *rect, const SDL_Color *color)
Definition Renderer.c:181

◆ renderDeviceDidReset()

static void renderDeviceDidReset ( View self)
static

Definition at line 1421 of file View.c.

1421 {
1423}
static void renderDeviceDidReset_enumerate(View *subview, ident data)
ViewEnumerator for renderDeviceDidReset recursion.
Definition View.c:1413

◆ renderDeviceDidReset_enumerate()

static void renderDeviceDidReset_enumerate ( View subview,
ident  data 
)
static

ViewEnumerator for renderDeviceDidReset recursion.

Definition at line 1413 of file View.c.

1413 {
1414 $(subview, renderDeviceDidReset);
1415}

◆ renderDeviceWillReset()

static void renderDeviceWillReset ( View self)
static

Definition at line 1436 of file View.c.

1436 {
1438}
static void renderDeviceWillReset_enumerate(View *subview, ident data)
ViewEnumerator for renderDeviceWillReset recursion.
Definition View.c:1428

◆ renderDeviceWillReset_enumerate()

static void renderDeviceWillReset_enumerate ( View subview,
ident  data 
)
static

ViewEnumerator for renderDeviceWillReset recursion.

Definition at line 1428 of file View.c.

1428 {
1429 $(subview, renderDeviceWillReset);
1430}

◆ renderFrame()

static SDL_Rect renderFrame ( const View self)
static

Definition at line 1444 of file View.c.

1444 {
1445
1446 SDL_Rect frame = self->frame;
1447
1448 const View *view = self;
1449 const View *superview = view->superview;
1450 while (superview) {
1451
1452 frame.x += superview->frame.x;
1453 frame.y += superview->frame.y;
1454
1455 if (view->alignment != ViewAlignmentInternal) {
1456 frame.x += superview->padding.left;
1457 frame.y += superview->padding.top;
1458 }
1459
1460 view = superview;
1461 superview = view->superview;
1462 }
1463
1464 return frame;
1465}
@ ViewAlignmentInternal
Definition View.h:78

◆ replaceSubview()

static void replaceSubview ( View self,
View subview,
View replacement 
)
static

Definition at line 1471 of file View.c.

1471 {
1472
1473 assert(subview);
1474 assert(replacement);
1475
1476 $(self, addSubviewRelativeTo, replacement, subview, ViewPositionAfter);
1477 $(self, removeSubview, subview);
1478}

◆ resignKeyResponder()

static void resignKeyResponder ( View self)
static

Definition at line 1484 of file View.c.

1484 {
1485
1486 if (self->window && $(self, isKeyResponder)) {
1487
1488 String *path = $(self, path);
1489 MVC_LogDebug("%s\n", path->chars);
1490 release(path);
1491
1492 SDL_SetPointerProperty(SDL_GetWindowProperties(self->window), "keyResponder", NULL);
1493 }
1494}

◆ resignTouchResponder()

static void resignTouchResponder ( View self)
static

Definition at line 1500 of file View.c.

1500 {
1501
1502 if (self->window && $(self, isTouchResponder)) {
1503
1504 String *path = $(self, path);
1505 MVC_LogDebug("%s\n", path->chars);
1506 release(path);
1507
1508 SDL_SetPointerProperty(SDL_GetWindowProperties(self->window), "touchResponder", NULL);
1509 }
1510}

◆ resize()

static void resize ( View self,
const SDL_Size *  size 
)
static

Definition at line 1516 of file View.c.

1516 {
1517
1518 const int w = clamp(size->w, self->minSize.w, self->maxSize.w);
1519 const int h = clamp(size->h, self->minSize.h, self->maxSize.h);
1520
1521 if (self->frame.w != w || self->frame.h != h) {
1522
1523 self->frame.w = w;
1524 self->frame.h = h;
1525
1526 self->needsLayout = true;
1527
1528 if (self->superview && $(self->superview, isContainer)) {
1529 self->superview->needsLayout = true;
1530 }
1531 }
1532}

◆ resolve()

static void resolve ( View self,
Outlet outlets 
)
static

Definition at line 1538 of file View.c.

1538 {
1539
1540 if (outlets) {
1541 for (Outlet *outlet = outlets; outlet->identifier; outlet++) {
1542 *outlet->view = $(self, descendantWithIdentifier, outlet->identifier);
1543 if (*outlet->view == NULL) {
1544 String *desc = $((Object *) self, description);
1545 MVC_LogError("Failed to resolve outlet '%s' for %s", outlet->identifier, desc->chars);
1546 release(desc);
1547 }
1548
1549 assert(*outlet->view);
1550 }
1551 }
1552}
Outlets enable outbound data binding of Views through JSON.
Definition View+JSON.h:200
const char * identifier
The View identifier.
Definition View+JSON.h:205

◆ respondToEvent()

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

Definition at line 1558 of file View.c.

1558 {
1559
1560 assert(event);
1561
1562 ViewEvent code = ViewEventNone;
1563
1564 switch (event->type) {
1565 case SDL_EVENT_MOUSE_BUTTON_DOWN:
1567 break;
1568 case SDL_EVENT_MOUSE_BUTTON_UP:
1570 $(self, resignTouchResponder);
1571 break;
1572 case SDL_EVENT_KEY_DOWN:
1573 code = ViewEventKeyDown;
1574 break;
1575 case SDL_EVENT_KEY_UP:
1576 code = ViewEventKeyUp;
1577 break;
1578 default:
1579 break;
1580 }
1581
1582 if (code != ViewEventNone) {
1583 $(self, emitViewEvent, code, NULL);
1584
1585 if (code == ViewEventMouseButtonUp) {
1586 if (event->button.clicks) {
1587 $(self, emitViewEvent, ViewEventClick, NULL);
1588 }
1589 }
1590 }
1591
1592 if (event->type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
1593 if ($(self, acceptsKeyResponder)) {
1594 $(self, becomeKeyResponder);
1595 return;
1596 }
1597 }
1598
1599 if (self->nextResponder) {
1600 $(self->nextResponder, respondToEvent, event);
1601 } else if (self->superview) {
1602 $(self->superview, respondToEvent, event);
1603 }
1604}
ViewEvent
View event relay codes.
Definition Types.h:61
@ ViewEventMouseButtonUp
A View has received a mouse button up event.
Definition Types.h:85
@ ViewEventMouseButtonDown
A View has received a mouse button down event.
Definition Types.h:80
@ ViewEventNone
No event.
Definition Types.h:65
@ ViewEventKeyUp
A View has received a key up event.
Definition Types.h:75
@ ViewEventClick
A Control received one or more click events.
Definition Types.h:115
@ ViewEventKeyDown
A View has received a key down event.
Definition Types.h:70
View * nextResponder
The next responder, or event handler, in the chain.
Definition View.h:229

◆ selectFirst()

static View * selectFirst ( View self,
const char *  rule 
)
static

Definition at line 1625 of file View.c.

1625 {
1626
1627 Selector *selector = $(alloc(Selector), initWithRule, rule);
1628 assert(selector);
1629
1630 View *first = $(selector, selectFirst, self);
1631
1632 release(selector);
1633 return first;
1634}

◆ size()

static SDL_Size size ( const View self)
static

Definition at line 1640 of file View.c.

1640 {
1641 return MakeSize(self->frame.w, self->frame.h);
1642}

◆ sizeThatContains()

static SDL_Size sizeThatContains ( const View self)
static

Definition at line 1648 of file View.c.

1648 {
1649
1650 const SDL_Size size = $(self, size);
1651 const SDL_Size sizeThatFits = $(self, sizeThatFits);
1652
1653 return MakeSize(max(size.w, sizeThatFits.w), max(size.h, sizeThatFits.h));
1654}

◆ sizeThatFills()

static SDL_Size sizeThatFills ( const View self)
static

Definition at line 1660 of file View.c.

1660 {
1661 SDL_Size size;
1662
1663 if (self->superview == NULL) {
1664 SDL_GetWindowSize(self->window, &size.w, &size.h);
1665 } else {
1666 size = $(self->superview, size);
1667 }
1668
1669 return size;
1670}

◆ sizeThatFits()

static SDL_Size sizeThatFits ( const View self)
static

Definition at line 1676 of file View.c.

1676 {
1677
1678 SDL_Size size = $(self, size);
1679
1681 size.w = 0;
1682 }
1683
1685 size.h = 0;
1686 }
1687
1688 if ($(self, isContainer)) {
1689 size = MakeSize(0, 0);
1690
1691 Array *subviews = $(self, visibleSubviews);
1692 for (size_t i = 0; i < subviews->count; i++) {
1693
1694 const View *subview = subviews->elements[i];
1695
1696 SDL_Size subviewSize;
1698 subviewSize = $(subview, sizeThatContains);
1699 } else if (subview->autoresizingMask & ViewAutoresizingFit) {
1700 subviewSize = $(subview, sizeThatFits);
1701 } else {
1702 subviewSize = $(subview, size);
1703 }
1704
1705 SDL_Point subviewOrigin = MakePoint(0, 0);
1706 switch (subview->alignment) {
1707 case ViewAlignmentNone:
1708 subviewOrigin = MakePoint(subview->frame.x, subview->frame.y);
1709 break;
1710 default:
1711 break;
1712 }
1713
1714 size.w = max(size.w, subviewOrigin.x + subviewSize.w);
1715 size.h = max(size.h, subviewOrigin.y + subviewSize.h);
1716 }
1717
1718 size.w += self->padding.left + self->padding.right;
1719 size.h += self->padding.top + self->padding.bottom;
1720
1721 release(subviews);
1722 }
1723
1724 size.w = clamp(size.w, self->minSize.w, self->maxSize.w);
1725 size.h = clamp(size.h, self->minSize.h, self->maxSize.h);
1726
1727 return size;
1728}
@ ViewAlignmentNone
Definition View.h:62

◆ sizeToContain()

static void sizeToContain ( View self)
static

Definition at line 1734 of file View.c.

1734 {
1735
1736 const SDL_Size size = $(self, sizeThatContains);
1737
1738 $(self, resize, &size);
1739}

◆ sizeToFill()

static void sizeToFill ( View self)
static

Definition at line 1745 of file View.c.

1745 {
1746
1747 const SDL_Size size = $(self, sizeThatFills);
1748
1749 $(self, resize, &size);
1750}

◆ sizeToFit()

static void sizeToFit ( View self)
static

Definition at line 1756 of file View.c.

1756 {
1757
1758 const SDL_Size size = $(self, sizeThatFits);
1759
1760 $(self, resize, &size);
1761}

◆ subviewWithIdentifier()

static View * subviewWithIdentifier ( const View self,
const char *  identifier 
)
static

Definition at line 1767 of file View.c.

1767 {
1768
1769 assert(identifier);
1770
1771 const Array *subviews = (Array *) self->subviews;
1772 for (size_t i = 0; i < subviews->count; i++) {
1773
1774 View *subview = subviews->elements[i];
1775 if (subview->identifier) {
1776
1777 if (strcmp(identifier, subview->identifier) == 0) {
1778 return subview;
1779 }
1780 }
1781 }
1782
1783 return NULL;
1784}

◆ updateBindings()

static void updateBindings ( View self)
static

Definition at line 1797 of file View.c.

1797 {
1799}
static void updateBindings_enumerate(View *subview, ident data)
ViewEnumerator for updateBindings recursion.
Definition View.c:1789

◆ updateBindings_enumerate()

static void updateBindings_enumerate ( View subview,
ident  data 
)
static

ViewEnumerator for updateBindings recursion.

Definition at line 1789 of file View.c.

1789 {
1790 $(subview, updateBindings);
1791}

◆ viewport()

static SDL_Rect viewport ( const View self)
static

Definition at line 1805 of file View.c.

1805 {
1806
1807 assert(self->window);
1808
1809 const SDL_Rect frame = $(self, renderFrame);
1810
1811 return MVC_TransformToWindow(self->window, &frame);
1812}
SDL_Rect MVC_TransformToWindow(SDL_Window *window, const SDL_Rect *rect)
Transforms the specified rectangle to normalized device coordinates in window.
Definition Window.c:29

◆ viewWithCharacters()

static View * viewWithCharacters ( const char *  chars,
Outlet outlets 
)
static

Definition at line 1818 of file View.c.

1818 {
1819
1820 Data *data = $$(Data, dataWithConstMemory, (ident) chars, strlen(chars));
1821
1822 View *view = $$(View, viewWithData, data, outlets);
1823
1824 release(data);
1825
1826 return view;
1827}

◆ viewWithData()

static View * viewWithData ( const Data *  data,
Outlet outlets 
)
static

Definition at line 1833 of file View.c.

1833 {
1834
1835 JSONContext *ctx = $(alloc(JSONContext), init);
1836 Dictionary *dictionary = $(ctx, objectFromData, data, 0);
1837
1838 View *view = NULL;
1839 if (dictionary) {
1840 view = $$(View, viewWithDictionary, dictionary, outlets);
1841 release(dictionary);
1842 } else {
1843 MVC_LogError("Failed to parse JSON\n");
1844 }
1845
1846 release(ctx);
1847 return view;
1848}

◆ viewWithDictionary()

static View * viewWithDictionary ( const Dictionary *  dictionary,
Outlet outlets 
)
static

Definition at line 1854 of file View.c.

1854 {
1855
1856 View *view = NULL;
1857
1858 BindInlet(&MakeInlet(NULL, InletTypeView, &view, NULL), dictionary);
1859
1860 $(view, resolve, outlets);
1861
1862 return view;
1863}
@ InletTypeView
Definition View+JSON.h:139
#define BindInlet(inlet, obj)
Binds the Inlet to obj by invoking the appropriate InletBinding function.
Definition View+JSON.h:244

◆ viewWithResource()

static View * viewWithResource ( const Resource *  resource,
Outlet outlets 
)
static

Definition at line 1869 of file View.c.

1869 {
1870
1871 assert(resource);
1872
1873 return $$(View, viewWithData, resource->data, outlets);
1874}

◆ viewWithResourceName()

static View * viewWithResourceName ( const char *  name,
Outlet outlets 
)
static

Definition at line 1880 of file View.c.

1880 {
1881
1882 Resource *resource = $$(Resource, resourceWithName, name);
1883
1884 View *view = $$(View, viewWithResource, resource, outlets);
1885
1886 release(resource);
1887
1888 return view;
1889}

◆ visibleSubviews()

static Array * visibleSubviews ( const View self)
static

Definition at line 1905 of file View.c.

1905 {
1906 return $((Array *) self->subviews, filteredArray, visibleSubviews_filter, NULL);
1907}
static bool visibleSubviews_filter(ident obj, ident data)
Predicate for visibleSubviews.
Definition View.c:1894

◆ visibleSubviews_filter()

static bool visibleSubviews_filter ( ident  obj,
ident  data 
)
static

Predicate for visibleSubviews.

Definition at line 1894 of file View.c.

1894 {
1895
1896 const View *view = (View *) obj;
1897
1898 return view->hidden == false && view->alignment != ViewAlignmentInternal;
1899}

◆ warn()

static void warn ( View self,
WarningType  type,
const char *  fmt,
  ... 
)
static

Definition at line 1913 of file View.c.

1913 {
1914
1915 va_list args;
1916 va_start(args, fmt);
1917
1918 Warning *warning = $(alloc(Warning), initWithVaList, type, fmt, args);
1919
1920 va_end(args);
1921
1922 String *description = $((Object *) self, description);
1923 MVC_LogWarn("%s:: %s\n", description->chars, warning->message->chars);
1924 release(description);
1925
1926 $(self->warnings, addObject, warning);
1927
1928 release(warning);
1929}
#define MVC_LogWarn(fmt,...)
Definition Log.h:54
static Warning * initWithVaList(Warning *self, WarningType type, const char *fmt, va_list args)
Definition Warning.c:66
String * message
The message.
Definition Warning.h:71

◆ willMoveToWindow()

static void willMoveToWindow ( View self,
SDL_Window *  window 
)
static

Definition at line 1935 of file View.c.

1935 {
1936
1937 if (self->window) {
1938 $(self, resignKeyResponder);
1939 $(self, resignTouchResponder);
1940 $(self, detachStylesheet, self->window);
1941 }
1942}

Variable Documentation

◆ MVC_NOTIFICATION_EVENT

Uint32 MVC_NOTIFICATION_EVENT

Definition at line 36 of file View.c.

◆ MVC_VIEW_EVENT

Uint32 MVC_VIEW_EVENT

Definition at line 37 of file View.c.

◆ ViewAlignmentNames

const EnumName ViewAlignmentNames[]
Initial value:
= MakeEnumNames(
MakeEnumAlias(ViewAlignmentNone, none),
MakeEnumAlias(ViewAlignmentTop, top),
MakeEnumAlias(ViewAlignmentMiddle, middle),
MakeEnumAlias(ViewAlignmentBottom, bottom),
MakeEnumAlias(ViewAlignmentLeft, left),
MakeEnumAlias(ViewAlignmentCenter, center),
MakeEnumAlias(ViewAlignmentRight, right),
MakeEnumAlias(ViewAlignmentTopLeft, top-left),
MakeEnumAlias(ViewAlignmentTopCenter, top-center),
MakeEnumAlias(ViewAlignmentTopRight, top-right),
MakeEnumAlias(ViewAlignmentMiddleLeft, middle-left),
MakeEnumAlias(ViewAlignmentMiddleCenter, middle-center),
MakeEnumAlias(ViewAlignmentMiddleRight, middle-right),
MakeEnumAlias(ViewAlignmentBottomLeft, bottom-left),
MakeEnumAlias(ViewAlignmentBottomCenter, bottom-center),
MakeEnumAlias(ViewAlignmentBottomRight, bottom-right),
MakeEnumAlias(ViewAlignmentInternal, internal)
)
@ ViewAlignmentBottomRight
Definition View.h:77
@ ViewAlignmentBottomLeft
Definition View.h:75
@ ViewAlignmentMiddleCenter
Definition View.h:73
@ ViewAlignmentTopCenter
Definition View.h:70
@ ViewAlignmentTopRight
Definition View.h:71
@ ViewAlignmentMiddleRight
Definition View.h:74
@ ViewAlignmentTopLeft
Definition View.h:69
@ ViewAlignmentTop
Definition View.h:63
@ ViewAlignmentMiddleLeft
Definition View.h:72
@ ViewAlignmentBottom
Definition View.h:65
@ ViewAlignmentMiddle
Definition View.h:64
@ ViewAlignmentBottomCenter
Definition View.h:76

Definition at line 39 of file View.c.

◆ ViewAutoresizingNames

const EnumName ViewAutoresizingNames[]
Initial value:
= MakeEnumNames(
MakeEnumAlias(ViewAutoresizingNone, none),
MakeEnumAlias(ViewAutoresizingWidth, width),
MakeEnumAlias(ViewAutoresizingHeight, height),
MakeEnumAlias(ViewAutoresizingFill, fill),
MakeEnumAlias(ViewAutoresizingFit, fit),
MakeEnumAlias(ViewAutoresizingContain, contain)
)
@ ViewAutoresizingNone
Definition View.h:87
@ ViewAutoresizingFill
Definition View.h:90

Definition at line 59 of file View.c.