ObjectivelyMVC 0.1.0
Object oriented MVC framework for OpenGL, SDL2 and GNU C
Public Member Functions | Data Fields | Protected Attributes
View Struct Reference

Views are the fundamental building blocks of ObjectivelyMVC user interfaces. More...

#include <View.h>

Inheritance diagram for View:
Box CollectionItemView Control ImageView Label Option PageView ProgressBar ScrollView StackView TabView TableCellView Text

Public Member Functions

Class * _View (void)
 The View archetype. More...
 
_Bool acceptsFirstResponder (const View *self)
 
void addClassName (View *self, const char *className)
 Adds the given class name to this View. More...
 
void addSubview (View *self, View *subview)
 Adds a subview to this view, to be drawn above its siblings. More...
 
void addSubviewRelativeTo (View *self, View *subview, View *other, ViewPosition position)
 Adds a subview to this view, positioned relatively to other. More...
 
 ancestorWithIdentifier (const View *self, const char *identifier)
 
void applyStyle (View *self, const Style *style)
 Applies the given Style to this View. More...
 
void applyTheme (View *self, const Theme *theme)
 Applies the given Theme to this View. More...
 
void applyThemeIfNeeded (View *self, const Theme *theme)
 Recursively applies the Theme to this View and its subviews. More...
 
void attachStylesheet (View *self, SDL_Window *window)
 Attaches this View's Stylesheet to the Theme associated with the given window. More...
 
void awakeWithCharacters (View *self, const char *chars)
 Wakes this View with the given null-terminated JSON C string. More...
 
void awakeWithData (View *self, const Data *data)
 Wakes this View with the specified JSON Data. More...
 
void awakeWithDictionary (View *self, const Dictionary *dictionary)
 Wakes this View with the specified Dictionary. More...
 
void awakeWithResource (View *self, const Resource *resource)
 Wakes this View with the specified Resource. More...
 
void awakeWithResourceName (View *self, const char *name)
 Wakes this View with the Resource by the specified name. More...
 
void becomeFirstResponder (View *self)
 Become the first responder in the View hierarchy. More...
 
_Bool bind (View *self, const Inlet *inlets, const Dictionary *dictionary)
 Performs data binding for the Inlets described in dictionary. More...
 
SDL_Rect bounds (const View *self)
 
void bringSubviewToFront (View *self, View *subview)
 Brings the specified subview to the front. More...
 
SDL_Rect clippingFrame (const View *self)
 
_Bool containsPoint (const View *self, const SDL_Point *point)
 
int depth (const View *self)
 
 descendantWithIdentifier (const View *self, const char *identifier)
 
void detachStylesheet (View *self, SDL_Window *window)
 Detaches this View's Stylesheet from the Theme associated with the given window. More...
 
void didMoveToWindow (View *self, SDL_Window *window)
 Informs this View that it has been added to the View hierachy of the given window. More...
 
_Bool didReceiveEvent (const View *self, const SDL_Event *event)
 
void * draw (View *self, Renderer *renderer)
 Draws this View. More...
 
void enumerate (const View *self, ViewEnumerator enumerator, ident data)
 
void enumerate (View *self, ViewEnumerator enumerator, ident data)
 Enumerates this View and its descendants, applying enumerator to each. More...
 
void enumerateAdjacent (const View *self, ViewEnumerator enumerator, ident data)
 Enumerates adjacent siblings of this View, applying enumerator to each. More...
 
void enumerateAncestors (const View *self, ViewEnumerator enumerator, ident data)
 Enumerates all ancestors of this View, applying enumerator to each. More...
 
void enumerateDescendants (const View *self, ViewEnumerator enumerator, ident data)
 Enumerates all descendants of this View, applying enumerator to each. More...
 
void enumerateSelection (View *self, const char *rule, ViewEnumerator enumerator, ident data)
 Enumerates all Views in the selection matched by rule, applying enumerator to each. More...
 
void enumerateSiblings (const View *self, ViewEnumerator enumerator, ident data)
 Enumerates all siblings of this View, applying enumerator to each. More...
 
void enumerateSubviews (const View *self, ViewEnumerator enumerator, ident data)
 Enumerates all subviews of this View, applying enumerator to each. More...
 
void enumerateSuperview (const View *self, ViewEnumerator enumerator, ident data)
 Enumerates the superview of this View, if any, applying enumerator to it. More...
 
ViewfirstResponder (SDL_Window *window)
 
_Bool hasClassName (const View *self, cosnt char *className)
 
ViewhitTest (const View *self, const SDL_Point *point)
 Performs a hit test against this View and its descendants for the given point. More...
 
Viewinit (View *self)
 Initializes this View. More...
 
ViewinitWithFrame (View *self, const SDL_Rect *frame)
 Initializes this View with the specified frame. More...
 
void invalidateStyle (View *self)
 Invalidates the computed Style for this View and its descendants. More...
 
_Bool isContainer (const View *self)
 
_Bool isDescendantOfView (const View *self, const View *view)
 
_Bool isFirstResponder (const View *self)
 
_Bool isVisible (const View *self)
 
void layoutIfNeeded (View *self)
 Recursively updates the layout of this View and its subviews. More...
 
 layoutSubviews (View *self)
 Performs layout for this View's immediate subviews. More...
 
_Bool matchesSelector (const View *self, const SimpleSelector *simpleSelector)
 
void moveToWindow (View *self, SDL_Window *window)
 Moves this View to the View hierarchy of the given window. More...
 
String * path (const View *self)
 
void removeAllClassNames (View *self)
 Removes all class names from this View. More...
 
void removeAllSubviews (View *self)
 Removes all subviews from this View. More...
 
void removeClassName (View *self, const char *className)
 Removes the given class name to this View. More...
 
void removeFromSuperview (View *self)
 Removes this View from its superview. More...
 
void removeSubview (View *self, View *subview)
 Removes the given subview from this View. More...
 
void render (View *self, Renderer *renderer)
 Renders this View using the given renderer. More...
 
void renderDeviceDidReset (View *self)
 Informs this View that the render device has reset. More...
 
void renderDeviceWillReset (View *self)
 Informs this View that the render device will reset. More...
 
SDL_Rect renderFrame (const View *self)
 
void replaceSubview (View *self, View *subview, View *replacement)
 Replaces the specified subview with the given replacement. More...
 
void resignFirstResponder (View *self)
 Resigns first responder priority. More...
 
void resize (View *self, const SDL_Size *size)
 Resizes this View to the specified size. More...
 
void resolve (View *self, Outlet *outlets)
 Resolves the given Outlets from this View's hierarchy. More...
 
void respondToEvent (View *self, const SDL_Event *event)
 Responds to the specified event. More...
 
Set * select (View *self, const char *rule)
 Resolves all descendants (including this View) that match the given Selector rule. More...
 
void setFirstResponder (SDL_Window *window, View *view)
 Sets the first responder for the given window. More...
 
SDL_Size size (const View *self)
 
SDL_Size sizeThatContains (const View *self)
 
void sizeThatFits (const View *self)
 
void sizeToContain (View *self)
 Resizes this View to contain its subviews. More...
 
void sizeToFit (View *self)
 Resizes this View to fit its subviews. More...
 
 subviewWithIdentifier (const View *self, const char *identifier)
 
void updateBindings (View *self)
 Updates data bindings, prompting the appropriate layout changes. More...
 
SDL_Rect viewport (const View *self)
 
ViewviewWithCharacters (const char *chars, Outlet *outlets)
 Instantiates a View initialized with the given null-terminated JSON C string. More...
 
ViewviewWithData (const Data *data, Outlet *outlets)
 Instantiates a View initialized with the contents of data. More...
 
ViewviewWithDictionary (const Dictionary *dictionary, Outlet *outlets)
 Instantiates a View initialized with the attributes described in dictionary. More...
 
ViewviewWithResource (const Resource *resource, Outlet *outlets)
 Instantiates a View initialized with the JSON data in resource. More...
 
ViewviewWithResourceName (const char *name, Outlet *outlets)
 Instantiates a View initialized with the JSON Resource with the specified name. More...
 
Array * visibleSubviews (const View *self)
 
void warn (View *self, const char *fmt,...)
 Appends a warning for this View. More...
 
void willMoveToWindow (View *self, SDL_Window *window)
 Informs this View that it will be added to the View hierarchy for the given window. More...
 

Data Fields

ViewAlignment alignment
 The alignment. More...
 
int autoresizingMask
 The ViewAutoresizing bitmask. More...
 
SDL_Color backgroundColor
 The background color. More...
 
SDL_Color borderColor
 The border color. More...
 
int borderWidth
 The border width. More...
 
MutableSet * classNames
 The class names. More...
 
_Bool clipsSubviews
 If true, subviews will be clipped to this View's frame. More...
 
StylecomputedStyle
 The computed Style of this View. More...
 
SDL_Rect frame
 The frame, relative to the superview. More...
 
_Bool hidden
 If true, this View is not drawn. More...
 
char * identifier
 An optional identifier. More...
 
SDL_Size maxSize
 The maximum size this View may be resized to during layout. More...
 
SDL_Size minSize
 The minimum size this View may be resized to during layout. More...
 
_Bool needsApplyTheme
 If true, this View will apply the Theme before it is drawn. More...
 
_Bool needsLayout
 If true, this View will layout its subviews before it is drawn. More...
 
ViewnextResponder
 The next responder, or event handler, in the chain. More...
 
Object object
 The superclass. More...
 
ViewPadding padding
 The padding. More...
 
Stylestyle
 The element-level Style of this View. More...
 
Stylesheetstylesheet
 An optional Stylesheet. More...
 
MutableArray * subviews
 The immediate subviews. More...
 
Viewsuperview
 The super View. More...
 
ViewControllerviewController
 The ViewController. More...
 
MutableArray * warnings
 The warnings this View generated. More...
 
SDL_Window * window
 The window. More...
 

Protected Attributes

ViewInterface * interface
 The interface. More...
 

Detailed Description

Views are the fundamental building blocks of ObjectivelyMVC user interfaces.

Views provide organization and coordination of layout, drawing and event handling. Views maintain hierarchical relationships among other Views, whereby each View's parent, or superview, dictates where it will be drawn on the screen, which events it will be eligible to receive, etc.

Definition at line 133 of file View.h.

Member Function Documentation

◆ _View()

Class * _View ( void  )

The View archetype.

Returns
The View Class.

Definition at line 1769 of file View.c.

1769 {
1770 static Class *clazz;
1771 static Once once;
1772
1773 do_once(&once, {
1774 clazz = _initialize(&(const ClassDef) {
1775 .name = "View",
1776 .superclass = _Object(),
1777 .instanceSize = sizeof(View),
1778 .interfaceOffset = offsetof(View, interface),
1779 .interfaceSize = sizeof(ViewInterface),
1781 });
1782 });
1783
1784 return clazz;
1785}
static void initialize(Class *clazz)
Definition: View.c:1677
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
Definition: View.h:133
ViewInterface * interface
The interface.
Definition: View.h:144

◆ acceptsFirstResponder()

_Bool acceptsFirstResponder ( const View self)
Parameters
selfThe View.
Returns
True if this View can become the first responder, false otherwise.

Definition at line 68 of file Control.c.

68 {
69 return true;
70}

◆ addClassName()

void addClassName ( View self,
const char *  className 
)

Adds the given class name to this View.

Parameters
selfThe View.
classNameThe class name.

Definition at line 120 of file View.c.

120 {
121
122 if (className) {
123
124 String *string = $$(String, stringWithCharacters, className);
125 assert(string);
126
127 $(self->classNames, addObject, string);
128 release(string);
129
130 $(self, invalidateStyle);
131 }
132}
void invalidateStyle(View *self)
Invalidates the computed Style for this View and its descendants.
Definition: View.c:822
MutableSet * classNames
The class names.
Definition: View.h:175

◆ addSubview()

void addSubview ( View self,
View subview 
)

Adds a subview to this view, to be drawn above its siblings.

Parameters
selfThe View.
subviewThe subview to add.
Remarks
This method is equivalent to $(view, addSubviewRelativeTo, subview, NULL, OrderSame).

Definition at line 35 of file PageView.c.

35 {
36
37 super(View, self, addSubview, subview);
38
39 PageView *this = (PageView *) self;
40
41 subview->hidden = true;
42
43 if (this->currentPage == NULL) {
44 $(this, setCurrentPage, subview);
45 }
46}
static void setCurrentPage(PageView *self, View *currentPage)
Definition: PageView.c:116
PageViews manage their subviews as pages in a book.
Definition: PageView.h:60
_Bool hidden
If true, this View is not drawn.
Definition: View.h:195
void addSubview(View *self, View *subview)
Adds a subview to this view, to be drawn above its siblings.
Definition: PageView.c:35

◆ addSubviewRelativeTo()

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

Adds a subview to this view, positioned relatively to other.

Parameters
selfThe View.
subviewThe subview to add.
otherAn optional View to position subview relative to.
positionThe relative position.

Definition at line 146 of file View.c.

146 {
147
148 assert(subview);
149 assert(subview != other);
150
151 retain(subview);
152
153 $(subview, removeFromSuperview);
154
155 if (other && other->superview == self) {
156
157 const Array *subviews = (Array *) self->subviews;
158 const ssize_t index = $(subviews, indexOfObject, other);
159
160 if (position == ViewPositionAfter) {
161 if (index == (ssize_t) (subviews->count - 1)) {
162 $(self->subviews, addObject, subview);
163 } else {
164 $(self->subviews, insertObjectAtIndex, subview, index + 1);
165 }
166 } else {
167 $(self->subviews, insertObjectAtIndex, subview, index);
168 }
169 } else {
170 $(self->subviews, addObject, subview);
171 }
172
173 release(subview);
174
175 subview->superview = self;
176
177 $(subview, moveToWindow, self->window);
178
179 $(subview, invalidateStyle);
180
181 self->needsLayout = true;
182}
@ ViewPositionAfter
Definition: View.h:120
MutableArray * subviews
The immediate subviews.
Definition: View.h:252
View * superview
The super View.
Definition: View.h:258
_Bool needsLayout
If true, this View will layout its subviews before it is drawn.
Definition: View.h:221
SDL_Window * window
The window.
Definition: View.h:276
void removeFromSuperview(View *self)
Removes this View from its superview.
Definition: View.c:1175
void moveToWindow(View *self, SDL_Window *window)
Moves this View to the View hierarchy of the given window.
Definition: View.c:1073

◆ ancestorWithIdentifier()

ancestorWithIdentifier ( const View self,
const char *  identifier 
)
Parameters
selfThe View.
identifierThe identifier.
Returns
The nearest ancestor View matching the given identifier.

Definition at line 188 of file View.c.

188 {
189
190 assert(identifier);
191
192 View *view = (View *) self;
193 while (view) {
194 if (view->identifier) {
195 if (strcmp(identifier, view->identifier) == 0) {
196 return view;
197 }
198 }
199 view = view->superview;
200 }
201
202 return NULL;
203}
char * identifier
An optional identifier.
Definition: View.h:201

◆ applyStyle()

void applyStyle ( View self,
const Style style 
)

Applies the given Style to this View.

Parameters
selfThe View.
styleThe Style.

Definition at line 56 of file CollectionView.c.

56 {
57
58 super(View, self, applyStyle, style);
59
60 CollectionView *this = (CollectionView *) self;
61
62 const Inlet inlets[] = MakeInlets(
63 MakeInlet("axis", InletTypeEnum, &this->axis, (ident) CollectionViewAxisNames),
64 MakeInlet("item-size", InletTypeSize, &this->itemSize, NULL),
65 MakeInlet("item-spacing", InletTypeSize, &this->itemSpacing, NULL)
66 );
67
68 $(self, bind, inlets, (Dictionary *) style->attributes);
69}
const EnumName CollectionViewAxisNames[]
@ InletTypeEnum
Definition: View+JSON.h:75
@ InletTypeSize
Definition: View+JSON.h:110
#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
CollectionViews display items in a grid.
Inlets enable inbound data binding of View attributes through JSON.
Definition: View+JSON.h:155
Dictionary * attributes
Definition: Style.h:59
_Bool bind(View *self, const Inlet *inlets, const Dictionary *dictionary)
Performs data binding for the Inlets described in dictionary.
Style * style
The element-level Style of this View.
Definition: View.h:240
void applyStyle(View *self, const Style *style)
Applies the given Style to this View.

◆ applyTheme()

void applyTheme ( View self,
const Theme theme 
)

Applies the given Theme to this View.

Parameters
selfThe View.
themeThe Theme.

Definition at line 246 of file View.c.

246 {
247
248 assert(theme);
249
251 assert(computedStyle);
252
254
255 release(self->computedStyle);
256 self->computedStyle = retain(computedStyle);
257
259 $(self, applyStyle, self->computedStyle);
260 }
261
262 release(computedStyle);
263}
static void addAttributes(Style *self, const Dictionary *attributes)
Definition: Style.c:119
static _Bool isComputedEqual(const Style *self, const Style *other)
Definition: Style.c:331
static Theme * theme(SDL_Window *window)
Definition: Theme.c:143
static Style * computeStyle(const Theme *self, const View *view)
Definition: Theme.c:103
The Style type.
Definition: Style.h:43
Style * computedStyle
The computed Style of this View.
Definition: View.h:185

◆ applyThemeIfNeeded()

void applyThemeIfNeeded ( View self,
const Theme theme 
)

Recursively applies the Theme to this View and its subviews.

Parameters
selfThe View.
themeThe Theme.

Definition at line 269 of file View.c.

269 {
270
271 assert(theme);
272
273 if (self->needsApplyTheme) {
274 $(self, applyTheme, theme);
275 }
276
277 self->needsApplyTheme = false;
278
280}
void(* ViewEnumerator)(View *view, ident data)
A function type for View enumeration.
Definition: Types.h:55
void applyThemeIfNeeded(View *self, const Theme *theme)
Recursively applies the Theme to this View and its subviews.
Definition: View.c:269
_Bool needsApplyTheme
If true, this View will apply the Theme before it is drawn.
Definition: View.h:216
void applyTheme(View *self, const Theme *theme)
Applies the given Theme to this View.
Definition: View.c:246
void enumerateSubviews(const View *self, ViewEnumerator enumerator, ident data)
Enumerates all subviews of this View, applying enumerator to each.
Definition: View.c:685

◆ attachStylesheet()

void attachStylesheet ( View self,
SDL_Window *  window 
)

Attaches this View's Stylesheet to the Theme associated with the given window.

Parameters
selfThe View.
windowThe window.

Definition at line 286 of file View.c.

286 {
287
288 assert(window);
289
290 if (self->stylesheet) {
291 Theme *theme = $$(Theme, theme, window);
292 if (theme) {
293 $(theme, addStylesheet, self->stylesheet);
294 }
295 }
296}
static void addStylesheet(Theme *self, Stylesheet *stylesheet)
Definition: Theme.c:55
The Theme type.
Definition: Theme.h:51
Stylesheet * stylesheet
An optional Stylesheet.
Definition: View.h:247

◆ awakeWithCharacters()

void awakeWithCharacters ( View self,
const char *  chars 
)

Wakes this View with the given null-terminated JSON C string.

Parameters
selfThe View.
charsA null-terminated JSON C string describing this View.
Remarks
This is a convenience method for View::awakeWithDictionary.

Definition at line 302 of file View.c.

302 {
303
304 Data *data = $$(Data, dataWithConstMemory, (uint8_t *) chars, strlen(chars));
305
306 $(self, awakeWithData, data);
307
308 release(data);
309}
void awakeWithData(View *self, const Data *data)
Wakes this View with the specified JSON Data.
Definition: View.c:315

◆ awakeWithData()

void awakeWithData ( View self,
const Data *  data 
)

Wakes this View with the specified JSON Data.

Parameters
selfThe View.
dataThe JSON Data containing properties describing this View.
Remarks
This is a convenience method for View::awakeWithDictionary.

Definition at line 315 of file View.c.

315 {
316
317 Dictionary *dictionary = $$(JSONSerialization, objectFromData, data, 0);
318
319 $(self, awakeWithDictionary, dictionary);
320
321 release(dictionary);
322}
void awakeWithDictionary(View *self, const Dictionary *dictionary)
Wakes this View with the specified Dictionary.
Definition: Box.c:50

◆ awakeWithDictionary()

void awakeWithDictionary ( View self,
const Dictionary *  dictionary 
)

Wakes this View with the specified Dictionary.

Parameters
selfThe View.
dictionaryA Dictionary of properties describing this View.
Remarks
This method is invoked when loading via JSON. Subclasses should override this method to perform any customization based on the contents of dictionary.

Definition at line 50 of file Box.c.

50 {
51
52 super(View, self, awakeWithDictionary, dictionary);
53
54 Box *this = (Box *) self;
55
56 const Inlet inlets[] = MakeInlets(
57 MakeInlet("contentView", InletTypeView, &this->contentView, NULL),
58 MakeInlet("label", InletTypeView, &this->label, NULL)
59 );
60
61 $(self, bind, inlets, dictionary);
62}
@ InletTypeView
Definition: View+JSON.h:139
A container View with a positioned Label.
Definition: Box.h:44

◆ awakeWithResource()

void awakeWithResource ( View self,
const Resource *  resource 
)

Wakes this View with the specified Resource.

Parameters
selfThe View.
resourceA Resource providing JSON data describing this View.

Definition at line 346 of file View.c.

346 {
347
348 assert(resource);
349
350 $(self, awakeWithData, resource->data);
351}

◆ awakeWithResourceName()

void awakeWithResourceName ( View self,
const char *  name 
)

Wakes this View with the Resource by the specified name.

Parameters
selfThe View.
nameThe name of a Resource providing JSON data describing this View.

Definition at line 357 of file View.c.

357 {
358
359 Resource *resource = $$(Resource, resourceWithName, name);
360
361 $(self, awakeWithResource, resource);
362
363 release(resource);
364}
void awakeWithResource(View *self, const Resource *resource)
Wakes this View with the specified Resource.
Definition: View.c:346

◆ becomeFirstResponder()

void becomeFirstResponder ( View self)

Become the first responder in the View hierarchy.

Parameters
selfThe View.
Remarks
Becoming the first responder gives a View priority when handling events.

Definition at line 370 of file View.c.

370 {
371 $$(View, setFirstResponder, self->window, self);
372}
void setFirstResponder(SDL_Window *window, View *view)
Sets the first responder for the given window.
Definition: View.c:1393

◆ bind()

_Bool bind ( View self,
const Inlet inlets,
const Dictionary *  dictionary 
)

Performs data binding for the Inlets described in dictionary.

Parameters
selfThe View.
inletsThe Inlets to bind.
dictionaryA Dictionary describing this View.
Returns
True if one or more Inlet was bound, false otherwise.
Remarks
Subclasses will typically call this method from View::awakeWithDictionary.

◆ bounds()

SDL_Rect bounds ( const View self)
Parameters
selfThe View.
Returns
The bounds (frame minus padding) of this View.

Definition at line 394 of file View.c.

394 {
395
396 const SDL_Size size = $(self, size);
397
398 const SDL_Rect bounds = {
399 .x = self->padding.left,
400 .y = self->padding.top,
401 .w = size.w - (self->padding.left + self->padding.right),
402 .h = size.h - (self->padding.top + self->padding.bottom),
403 };
404
405 return bounds;
406}
The SDL_Size type.
Definition: Types.h:62
int w
Definition: Types.h:63
int h
Definition: Types.h:63
SDL_Rect bounds(const View *self)
Definition: View.c:394
SDL_Size size(const View *self)
Definition: View.c:1415
ViewPadding padding
The padding.
Definition: View.h:233
int top
Definition: View.h:100
int bottom
Definition: View.h:100
int right
Definition: View.h:100
int left
Definition: View.h:100

◆ bringSubviewToFront()

void bringSubviewToFront ( View self,
View subview 
)

Brings the specified subview to the front.

Parameters
selfThe View.
subviewThe subview.

Definition at line 412 of file View.c.

412 {
413
414 assert(subview);
415
416 if (subview->superview == self) {
417
418 View *last = $((Array *) self->subviews, lastObject);
419 if (last != subview) {
420 $(self, addSubviewRelativeTo, subview, last, ViewPositionAfter);
421 }
422 }
423}
void addSubviewRelativeTo(View *self, View *subview, View *other, ViewPosition position)
Adds a subview to this view, positioned relatively to other.
Definition: View.c:146

◆ clippingFrame()

SDL_Rect clippingFrame ( const View self)
Parameters
selfThe View.
Returns
The visible portion of this View's frame, in window coordinates.
Remarks
This is equivalent to the View's renderFrame, expanded for border width, and clipped to all ancestors.

Definition at line 429 of file View.c.

429 {
430
431 SDL_Rect frame = $(self, renderFrame);
432
433 if (self->borderWidth && self->borderColor.a) {
434 for (int i = 0; i < self->borderWidth; i++) {
435 frame.x -= 1;
436 frame.y -= 1;
437 frame.w += 2;
438 frame.h += 2;
439 }
440 }
441
442 const View *superview = self->superview;
443 while (superview) {
445 const SDL_Rect clippingFrame = $(superview, clippingFrame);
446 if (SDL_IntersectRect(&clippingFrame, &frame, &frame) == false) {
447
448 if (MVC_LogEnabled(SDL_LOG_PRIORITY_VERBOSE)) {
449 String *desc = $((Object *) self, description);
450 String *superdesc = $((Object *) superview, description);
451
452 MVC_LogVerbose("%s is clipped by %s\n", desc->chars, superdesc->chars);
453
454 release(desc);
455 release(superdesc);
456 }
457
458 frame.w = frame.h = 0;
459 break;
460 }
461 }
463 }
464
465 return frame;
466}
#define MVC_LogVerbose(fmt,...)
Definition: Log.h:43
#define MVC_LogEnabled(priority)
Definition: Log.h:37
static String * description(const Object *self)
Definition: View.c:91
SDL_Rect clippingFrame(const View *self)
Definition: View.c:429
_Bool clipsSubviews
If true, subviews will be clipped to this View's frame.
Definition: View.h:180
SDL_Color borderColor
The border color.
Definition: View.h:164
int borderWidth
The border width.
Definition: View.h:169
SDL_Rect renderFrame(const View *self)
Definition: View.c:1275
SDL_Rect frame
The frame, relative to the superview.
Definition: View.h:190

◆ containsPoint()

_Bool containsPoint ( const View self,
const SDL_Point *  point 
)
Parameters
selfThe View.
pointA point in object space.
Returns
True if the point falls within this View's clipped frame.

Definition at line 472 of file View.c.

472 {
473
474 const SDL_Rect frame = $(self, clippingFrame);
475
476 return (_Bool) !!SDL_PointInRect(point, &frame);
477}

◆ depth()

int depth ( const View self)
Parameters
selfThe View.
Returns
The depth of this View (ancestor depth + 1).

Definition at line 483 of file View.c.

483 {
484 return (self->superview ? $(self->superview, depth) + 1 : 0);
485}
int depth(const View *self)
Definition: View.c:483

◆ descendantWithIdentifier()

descendantWithIdentifier ( const View self,
const char *  identifier 
)
Parameters
selfThe View.
identifierThe identifier.
Returns
The nearest descendant View matching the given identifier.

Definition at line 491 of file View.c.

491 {
492
493 assert(identifier);
494
495 if (self->identifier) {
496 if (strcmp(identifier, self->identifier) == 0) {
497 return (View *) self;
498 }
499 }
500
501 const Array *subviews = (Array *) self->subviews;
502 for (size_t i = 0; i < subviews->count; i++) {
503 const View *subview = $(subviews, objectAtIndex, i);
504 View *descendant = $(subview, descendantWithIdentifier, identifier);
505 if (descendant) {
506 return descendant;
507 }
508 }
509
510 return NULL;
511}
descendantWithIdentifier(const View *self, const char *identifier)
Definition: View.c:491

◆ detachStylesheet()

void detachStylesheet ( View self,
SDL_Window *  window 
)

Detaches this View's Stylesheet from the Theme associated with the given window.

Parameters
selfThe View.
windowThe window.

Definition at line 517 of file View.c.

517 {
518
519 assert(window);
520
521 if (self->stylesheet) {
522 Theme *theme = $$(Theme, theme, window);
523 if (theme) {
525 }
526 }
527}
static void removeStylesheet(Theme *self, Stylesheet *stylesheet)
Definition: Theme.c:135

◆ didMoveToWindow()

void didMoveToWindow ( View self,
SDL_Window *  window 
)

Informs this View that it has been added to the View hierachy of the given window.

Parameters
selfThe View.
windowThe window, or NULL if this View has been removed from the window.

Definition at line 533 of file View.c.

533 {
534
535 if (window) {
536 $(self, attachStylesheet, window);
537
538 self->needsLayout = true;
539 }
540}
void attachStylesheet(View *self, SDL_Window *window)
Attaches this View's Stylesheet to the Theme associated with the given window.
Definition: View.c:286

◆ didReceiveEvent()

_Bool didReceiveEvent ( const View self,
const SDL_Event *  event 
)
Parameters
selfThe View.
eventThe event.
Returns
True if this View received the event, false otherwise.

Definition at line 546 of file View.c.

546 {
547
548 if ($(self, isVisible)) {
549
550 SDL_Point point;
551
552 if (event->type == SDL_MOUSEBUTTONDOWN || event->type == SDL_MOUSEBUTTONUP) {
553 point = MakePoint(event->button.x, event->button.y);
554 } else if (event->type == SDL_MOUSEMOTION) {
555 point = MakePoint(event->motion.x, event->motion.y);
556 } else if (event->type == SDL_MOUSEWHEEL) {
557 SDL_GetMouseState(&point.x, &point.y);
558 } else {
559 return false;
560 }
561
562 return $(self, containsPoint, &point);
563 }
564
565 return false;
566}
#define MakePoint(x, y)
Creates an SDL_Point with the given coordinates.
Definition: Types.h:69
_Bool isVisible(const View *self)
Definition: View.c:869
_Bool containsPoint(const View *self, const SDL_Point *point)
Definition: View.c:472

◆ draw()

void draw ( View self,
Renderer renderer 
)

Draws this View.

Parameters
selfThe View.
rendererThe Renderer.
Remarks
This method determines if the View is visible and dispatches Renderer::drawView before recursing down the View hierarchy. Rasterization is performed in View::render.
See also
View::render(View *, Renderer *)

Definition at line 572 of file View.c.

572 {
573
574 assert(self->window);
575
576 if (self->hidden == false) {
577
578 $(renderer, drawView, self);
579
580 $(self, enumerateSubviews, (ViewEnumerator) draw, renderer);
581 }
582}
static void drawView(Renderer *self, View *view)
Definition: Renderer.c:195
void * draw(View *self, Renderer *renderer)
Draws this View.
Definition: View.c:572

◆ enumerate() [1/2]

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

◆ enumerate() [2/2]

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

Enumerates this View and its descendants, applying enumerator to each.

Parameters
selfThe View.
enumeratorThe ViewEnumerator.
dataUser data.

Definition at line 588 of file View.c.

588 {
589
590 assert(enumerator);
591
592 enumerator(self, data);
593
594 $(self, enumerateDescendants, enumerator, data);
595}
void enumerateDescendants(const View *self, ViewEnumerator enumerator, ident data)
Enumerates all descendants of this View, applying enumerator to each.
Definition: View.c:647

◆ enumerateAdjacent()

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

Enumerates adjacent siblings of this View, applying enumerator to each.

Parameters
selfThe View.
enumeratorThe ViewEnumerator.
dataUser data.

Definition at line 601 of file View.c.

601 {
602
603 assert(enumerator);
604
605 if (self->superview) {
606 const Array *siblings = (Array *) self->superview->subviews;
607 const ssize_t index = $(siblings, indexOfObject, (const ident) self);
608 if (index > 0) {
609 enumerator($(siblings, objectAtIndex, index - 1), data);
610 }
611 if (index < (ssize_t) (siblings->count - 1)) {
612 enumerator($(siblings, objectAtIndex, index + 1), data);
613 }
614 }
615}

◆ enumerateAncestors()

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

Enumerates all ancestors of this View, applying enumerator to each.

Parameters
selfThe View.
enumeratorThe ViewEnumerator.
dataUser data.

Definition at line 621 of file View.c.

621 {
622
623 assert(enumerator);
624
625 for (View *view = self->superview; view; view = view->superview) {
626 enumerator(view, data);
627 }
628}

◆ enumerateDescendants()

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

Enumerates all descendants of this View, applying enumerator to each.

Parameters
selfThe View.
enumeratorThe ViewEnumerator.
dataUser data.

Definition at line 647 of file View.c.

647 {
648
649 assert(enumerator);
650
651 const Array *subviews = (Array *) self->subviews;
652 for (size_t i = 0; i < subviews->count; i++) {
653
654 View *subview = $(subviews, objectAtIndex, i);
655 enumerator(subview, data);
656
657 $(subview, enumerateDescendants, enumerator, data);
658 }
659}

◆ enumerateSelection()

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

Enumerates all Views in the selection matched by rule, applying enumerator to each.

Parameters
selfThe View.
ruleThe Selector rule.
enumeratorThe ViewEnumerator.
dataUser data.

Definition at line 634 of file View.c.

634 {
635
636 Selector *selector = $(alloc(Selector), initWithRule, rule);
637 assert(selector);
638
639 $(selector, enumerateSelection, self, enumerator, data);
640 release(selector);
641}
static Selector * initWithRule(Selector *self, const char *rule)
Definition: Selector.c:188
Selectors are comprised of one or more SelectorSequences.
Definition: Selector.h:49
void enumerateSelection(View *self, const char *rule, ViewEnumerator enumerator, ident data)
Enumerates all Views in the selection matched by rule, applying enumerator to each.
Definition: View.c:634

◆ enumerateSiblings()

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

Enumerates all siblings of this View, applying enumerator to each.

Parameters
selfThe View.
enumeratorThe ViewEnumerator.
dataUser data.

Definition at line 665 of file View.c.

665 {
666
667 assert(enumerator);
668
669 if (self->superview) {
670
671 const Array *siblings = (Array *) self->superview->subviews;
672 for (size_t i = 0; i < siblings->count; i++) {
673 View *sibling = $(siblings, objectAtIndex, i);
674 if (sibling != self) {
675 enumerator(sibling, data);
676 }
677 }
678 }
679}

◆ enumerateSubviews()

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

Enumerates all subviews of this View, applying enumerator to each.

Parameters
selfThe View.
enumeratorThe ViewEnumerator.
dataUser data.

Definition at line 685 of file View.c.

685 {
686
687 assert(enumerator);
688
689 const Array *subviews = (Array *) self->subviews;
690 for (size_t i = 0; i < subviews->count; i++) {
691 enumerator((View *) subviews->elements[i], data);
692 }
693}

◆ enumerateSuperview()

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

Enumerates the superview of this View, if any, applying enumerator to it.

Parameters
selfThe View.
enumeratorThe ViewEnumerator.
dataUser data.

Definition at line 699 of file View.c.

699 {
700
701 assert(enumerator);
702
703 if (self->superview) {
704 enumerator(self->superview, data);
705 }
706}

◆ firstResponder()

View * firstResponder ( SDL_Window *  window)
Parameters
windowThe window.
Returns
The first responder for the given window, or NULL if none.

Definition at line 712 of file View.c.

712 {
713
714 assert(window);
715
716 return SDL_GetWindowData(window, "firstResponder");
717}

◆ hasClassName()

_Bool hasClassName ( const View self,
cosnt char *  className 
)
Parameters
selfThe View
classNameThe class name.
Returns
True if this View has the given class name, false otherwise.

◆ hitTest()

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

Performs a hit test against this View and its descendants for the given point.

Parameters
selfThe View.
pointThe point to test.
Returns
The furthest descendant View that contains the given point.

Definition at line 743 of file View.c.

743 {
744
745 if (self->hidden == false) {
746
747 if ($(self, containsPoint, point)) {
748
749 const Array *subviews = (Array *) self->subviews;
750 for (size_t i = subviews->count; i; i--) {
751
752 const View *subview = $(subviews, objectAtIndex, i - 1);
753 const View *view = $(subview, hitTest, point);
754 if (view) {
755 return (View *) view;
756 }
757 }
758
759 return (View *) self;
760 }
761 }
762
763 return NULL;
764}
View * hitTest(const View *self, const SDL_Point *point)
Performs a hit test against this View and its descendants for the given point.
Definition: View.c:743

◆ init()

View * init ( View self)

Initializes this View.

Parameters
selfThe View.
Returns
The initialized View, or NULL on error.
Remarks
View::viewWithDictionary invokes this initializer when loading Views. Subclasses wishing to support JSON binding must override this method to call their designated initializer.

Definition at line 67 of file Box.c.

67 {
68 return (View *) $((Box *) self, initWithFrame, NULL);
69}
View * initWithFrame(View *self, const SDL_Rect *frame)
Initializes this View with the specified frame.
Definition: View.c:778

◆ initWithFrame()

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

Initializes this View with the specified frame.

Parameters
selfThe View.
frameThe frame.
Returns
The initialized View, or NULL on error.
Remarks
Designated initializer.

Definition at line 778 of file View.c.

778 {
779
780 self = (View *) super(Object, self, init);
781 if (self) {
782
783 if (frame) {
784 self->frame = *frame;
785 }
786
787 self->classNames = $$(MutableSet, setWithCapacity, 0);
788 assert(self->classNames);
789
790 self->computedStyle = $(alloc(Style), initWithAttributes, NULL);
791 assert(self->computedStyle);
792
793 self->subviews = $$(MutableArray, arrayWithCapacity, 0);
794 assert(self->subviews);
795
796 self->style = $(alloc(Style), initWithAttributes, NULL);
797 assert(self->style);
798
799 self->warnings = $$(MutableArray, arrayWithCapacity, 0);
800 assert(self->warnings);
801
802 self->maxSize = MakeSize(INT32_MAX, INT32_MAX);
803
804 self->needsApplyTheme = true;
805 self->needsLayout = true;
806 }
807
808 return self;
809}
static Style * initWithAttributes(Style *self, const Dictionary *attributes)
Definition: Style.c:292
#define MakeSize(w, h)
Creates an SDL_Size with the given dimensions.
Definition: Types.h:79
MutableArray * warnings
The warnings this View generated.
Definition: View.h:270
SDL_Size maxSize
The maximum size this View may be resized to during layout.
Definition: View.h:206
View * init(View *self)
Initializes this View.
Definition: Box.c:67

◆ invalidateStyle()

void invalidateStyle ( View self)

Invalidates the computed Style for this View and its descendants.

Parameters
selfThe View.

Definition at line 822 of file View.c.

822 {
823 $(self, enumerate, invalidateStyle_enumerate, NULL);
824}
static void invalidateStyle_enumerate(View *view, ident data)
ViewEnumerator for invalidateStyle.
Definition: View.c:814
void enumerate(const View *self, ViewEnumerator enumerator, ident data)

◆ isContainer()

_Bool isContainer ( const View self)
Parameters
selfThe view.
Returns
True if this View's autoresizing mask includes Fit or Contain.

Definition at line 830 of file View.c.

830 {
832}
@ ViewAutoresizingContain
Definition: View.h:91
@ ViewAutoresizingFit
Definition: View.h:90
int autoresizingMask
The ViewAutoresizing bitmask.
Definition: View.h:154

◆ isDescendantOfView()

_Bool isDescendantOfView ( const View self,
const View view 
)
Parameters
selfThe View.
viewThe View to test against this View's hierarchy.
Returns
True if this View is a descendant of, or equal to, the given View.

Definition at line 838 of file View.c.

838 {
839
840 assert(view);
841
842 while (self) {
843 if (self == view) {
844 return true;
845 }
846 self = self->superview;
847 }
848
849 return false;
850}

◆ isFirstResponder()

_Bool isFirstResponder ( const View self)
Parameters
selfThe View.
Returns
True if this View is the first responder, false otherwise.

Definition at line 856 of file View.c.

856 {
857
858 if (self->window) {
859 return $$(View, firstResponder, self->window) == self;
860 } else {
861 return false;
862 }
863}
View * firstResponder(SDL_Window *window)
Definition: View.c:712

◆ isVisible()

_Bool isVisible ( const View self)
Parameters
selfThe View.
Returns
True if this View is visible, false if it, or an ancestor, is hidden.

Definition at line 869 of file View.c.

869 {
870
871 for (const View *view = self; view; view = view->superview) {
872 if (view->hidden) {
873 return false;
874 }
875 }
876
877 return true;
878}

◆ layoutIfNeeded()

void layoutIfNeeded ( View self)

Recursively updates the layout of this View and its subviews.

Parameters
selfThe View.

Definition at line 891 of file View.c.

891 {
892
893 if (self->needsLayout) {
894 $(self, layoutSubviews);
895
896 if (MVC_LogEnabled(SDL_LOG_PRIORITY_DEBUG)) {
897
898 if (self->hidden == false && self->superview && self->superview->clipsSubviews) {
899
900 const SDL_Rect bounds = $(self, bounds);
901 const SDL_Rect superviewBounds = $(self->superview, bounds);
902
903 if (bounds.x + bounds.w > superviewBounds.w ||
904 bounds.y + bounds.h > superviewBounds.h) {
905
906 String *this = $((Object *) self, description);
907 String *that = $((Object *) self->superview, description);
908
909 MVC_LogDebug("%s exceeds superview bounds %s\n", this->chars, that->chars);
910
911 $(self, warn, "%s exceeds superview bounds %s\n", this->chars, that->chars);
912
913 release(this);
914 release(that);
915 }
916 }
917 }
918 }
919
920 self->needsLayout = false;
921
923}
#define MVC_LogDebug(fmt,...)
Definition: Log.h:46
static void layoutIfNeeded_recurse(View *subview, ident data)
ViewEnumerator for layoutIfNeeded recursion.
Definition: View.c:883
void warn(View *self, const char *fmt,...)
Appends a warning for this View.
Definition: View.c:1647
layoutSubviews(View *self)
Performs layout for this View's immediate subviews.
Definition: Box.c:74

◆ layoutSubviews()

layoutSubviews ( View self)

Performs layout for this View's immediate subviews.

Parameters
selfThe View.
Remarks
Subclasses may override this method to perform their own layout operations. This method is called recursively by View::layoutIfNeeded.

Definition at line 74 of file Box.c.

74 {
75
76 super(View, self, layoutSubviews);
77
78 View *label = (View *) ((Box *) self)->label;
79 if (label->hidden == false) {
80
81 const SDL_Size size = $(label, sizeThatContains);
82 label->frame.y = -size.h * 0.5;
83 }
84}
SDL_Size sizeThatContains(const View *self)
Definition: View.c:1423

◆ matchesSelector()

_Bool matchesSelector ( const View self,
const SimpleSelector simpleSelector 
)
Parameters
selfThe View.
simpleSelectorThe SimpleSelector.
Returns
True if this View matches the SimpleSelector, false otherwise.

Definition at line 51 of file CollectionItemView.c.

51 {
52
53 assert(simpleSelector);
54
55 const CollectionItemView *this = (CollectionItemView *) self;
56 const char *pattern = simpleSelector->pattern;
57
58 switch (simpleSelector->type) {
60 if (strcmp("selected", pattern) == 0) {
61 return this->isSelected;
62 }
63 break;
64 default:
65 break;
66 }
67
68 return super(View, self, matchesSelector, simpleSelector);
69}
static _Bool isSelected(const Control *self)
Definition: Control.c:325
@ SimpleSelectorTypePseudo
CollectionViewItems are a visual representation of an item within a CollectionView.
SimpleSelectorType type
The SimpleSelectorType.
char * pattern
The pattern, as provided by the user.
_Bool matchesSelector(const View *self, const SimpleSelector *simpleSelector)

◆ moveToWindow()

void moveToWindow ( View self,
SDL_Window *  window 
)

Moves this View to the View hierarchy of the given window.

Parameters
selfThe View.
windowThe window, or NULL if this View is moving from its current window.

Definition at line 1073 of file View.c.

1073 {
1074
1075 if (self->window != window) {
1076
1077 $(self, willMoveToWindow, window);
1078
1079 self->window = window;
1080
1081 $(self, didMoveToWindow, window);
1082
1084 }
1085}
static void moveToWindow_recurse(View *subview, ident data)
ViewEnumerator for moveToWindow recursion.
Definition: View.c:1065
void didMoveToWindow(View *self, SDL_Window *window)
Informs this View that it has been added to the View hierachy of the given window.
Definition: View.c:533
void willMoveToWindow(View *self, SDL_Window *window)
Informs this View that it will be added to the View hierarchy for the given window.
Definition: View.c:1664

◆ path()

String * path ( const View self)
Parameters
selfThe view.
Returns
A unique CSS selector matching this View.

Definition at line 1091 of file View.c.

1091 {
1092
1093 MutableArray *parts = $$(MutableArray, array);
1094
1095 const View *view = self;
1096 while (view) {
1097
1098 Array *classNames = $((Set *) view->classNames, allObjects);
1099
1100 String *part;
1101 if (view->identifier) {
1102 part = str("#%s", view->identifier);
1103 } else if (classNames->count) {
1104 part = str(".%s", ((String *) $(classNames, firstObject))->chars);
1105 } else {
1106 part = str("%s", classnameof(view));
1107 }
1108
1109 release(classNames);
1110
1111 $(parts, insertObjectAtIndex, part, 0);
1112 release(part);
1113
1114 if (view->viewController) {
1115 break;
1116 }
1117
1118 view = view->superview;
1119 }
1120
1121 String *path = $((Array *) parts, componentsJoinedByCharacters, " > ");
1122
1123 release(parts);
1124
1125 return path;
1126}
String * path(const View *self)
Definition: View.c:1091
ViewController * viewController
The ViewController.
Definition: View.h:264

◆ removeAllClassNames()

void removeAllClassNames ( View self)

Removes all class names from this View.

Parameters
selfThe View.

Definition at line 1132 of file View.c.

1132 {
1133
1134 $(self->classNames, removeAllObjects);
1135
1136 $(self, invalidateStyle);
1137}

◆ removeAllSubviews()

void removeAllSubviews ( View self)

Removes all subviews from this View.

Parameters
selfThe View.

Definition at line 1150 of file View.c.

1150 {
1151 $(self->subviews, removeAllObjectsWithEnumerator, removeAllSubviews_enumerate, self);
1152}
static void removeAllSubviews_enumerate(const Array *array, ident obj, ident data)
ArrayEnumerator for removeAllSubviews.
Definition: View.c:1142

◆ removeClassName()

void removeClassName ( View self,
const char *  className 
)

Removes the given class name to this View.

Parameters
selfThe View.
classNameThe class name.

Definition at line 1158 of file View.c.

1158 {
1159
1160 if (className) {
1161 String *string = $$(String, stringWithCharacters, className);
1162 assert(string);
1163
1164 $(self->classNames, removeObject, string);
1165 release(string);
1166
1167 $(self, invalidateStyle);
1168 }
1169}

◆ removeFromSuperview()

void removeFromSuperview ( View self)

Removes this View from its superview.

Parameters
selfThe View.

Definition at line 1175 of file View.c.

1175 {
1176
1177 if (self->superview) {
1178 $(self->superview, removeSubview, self);
1179 }
1180}
void removeSubview(View *self, View *subview)
Removes the given subview from this View.
Definition: PageView.c:58

◆ removeSubview()

void removeSubview ( View self,
View subview 
)

Removes the given subview from this View.

Parameters
selfThe View.
subviewThe subview.

Definition at line 58 of file PageView.c.

58 {
59
60 PageView *this = (PageView *) self;
61
62 retain(subview);
63
64 super(View, self, removeSubview, subview);
65
66 subview->hidden = false;
67
68 if (subview == this->currentPage) {
69 $(this, setCurrentPage, NULL);
70 }
71
72 release(subview);
73}

◆ render()

void render ( View self,
Renderer renderer 
)

Renders this View using the given renderer.

Parameters
selfThe View.
rendererThe Renderer.
Remarks
Subclasses should override this method to perform actual drawing operations. This method is called by draw as the View hierarchy is drawn.

Definition at line 131 of file Control.c.

131 {
132
133 super(View, self, render, renderer);
134
135 Control *this = (Control *) self;
136
137 const SDL_Rect frame = $(self, renderFrame);
138
139 if (this->bevel == ControlBevelInset) {
140
141 $(renderer, setDrawColor, &Colors.Silver);
142
143 SDL_Point points[3];
144
145 points[0].x = frame.x;
146 points[0].y = frame.y + frame.h;
147
148 points[1].x = frame.x + frame.w;
149 points[1].y = frame.y + frame.h;
150
151 points[2].x = frame.x + frame.w;
152 points[2].y = frame.y;
153
154 $(renderer, drawLines, points, lengthof(points));
155
156 $(renderer, setDrawColor, &Colors.Black);
157
158 points[0].x = frame.x;
159 points[0].y = frame.y + frame.h;
160
161 points[1].x = frame.x;
162 points[1].y = frame.y;
163
164 points[2].x = frame.x + frame.w;
165 points[2].y = frame.y;
166
167 $(renderer, drawLines, points, lengthof(points));
168
169 } else if (this->bevel == ControlBevelOutset) {
170
171 $(renderer, setDrawColor, &Colors.Black);
172
173 SDL_Point points[3];
174
175 points[0].x = frame.x;
176 points[0].y = frame.y + frame.h;
177
178 points[1].x = frame.x + frame.w;
179 points[1].y = frame.y + frame.h;
180
181 points[2].x = frame.x + frame.w;
182 points[2].y = frame.y;
183
184 $(renderer, drawLines, points, lengthof(points));
185
186 $(renderer, setDrawColor, &Colors.Silver);
187
188 points[0].x = frame.x;
189 points[0].y = frame.y + frame.h;
190
191 points[1].x = frame.x;
192 points[1].y = frame.y;
193
194 points[2].x = frame.x + frame.w;
195 points[2].y = frame.y;
196
197 $(renderer, drawLines, points, lengthof(points));
198 }
199
200 if (this->state & ControlStateFocused) {
201
202 $(renderer, setDrawColor, &Colors.Charcoal);
203
204 $(renderer, drawRect, &frame);
205 }
206
207 $(renderer, setDrawColor, &Colors.White);
208}
@ ControlBevelInset
Definition: Control.h:46
@ ControlBevelOutset
Definition: Control.h:47
@ ControlStateFocused
Definition: Control.h:71
static void setDrawColor(Renderer *self, const SDL_Color *color)
Definition: Renderer.c:281
static void drawLines(const Renderer *self, const SDL_Point *points, size_t count)
Definition: Renderer.c:105
static void drawRect(const Renderer *self, const SDL_Rect *rect)
Definition: Renderer.c:118
W3C Color constants.
Definition: Colors.h:37
SDL_Color White
Definition: Colors.h:185
SDL_Color Charcoal
Definition: Colors.h:53
SDL_Color Black
Definition: Colors.h:46
SDL_Color Silver
Definition: Colors.h:169
Controls are Views which capture events and dispatch Actions.
Definition: Control.h:83
void render(View *self, Renderer *renderer)
Renders this View using the given renderer.
Definition: Control.c:131

◆ renderDeviceDidReset()

void renderDeviceDidReset ( View self)

Informs this View that the render device has reset.

Parameters
selfThe View.
Remarks
Subclasses may override this method to allocate any OpenGL objects they require.

Definition at line 172 of file Text.c.

172 {
173
174 Text *this = (Text *) self;
175
176 $(this->font, renderDeviceDidReset);
177
178 super(View, self, renderDeviceDidReset);
179}
Text rendered with TrueType fonts.
Definition: Text.h:41
void renderDeviceDidReset(View *self)
Informs this View that the render device has reset.
Definition: Text.c:172

◆ renderDeviceWillReset()

void renderDeviceWillReset ( View self)

Informs this View that the render device will reset.

Parameters
selfThe View.
Remarks
Subclasses should override this method to free any OpenGL objects they own.

Definition at line 121 of file ImageView.c.

121 {
122
123 ImageView *this = (ImageView *) self;
124
125 if (this->texture) {
126 glDeleteTextures(1, &this->texture);
127 }
128
129 this->texture = 0;
130
131 super(View, self, renderDeviceWillReset);
132}
ImageViews render an Image in the context of a View hierarchy.
Definition: ImageView.h:43
void renderDeviceWillReset(View *self)
Informs this View that the render device will reset.
Definition: ImageView.c:121

◆ renderFrame()

SDL_Frame renderFrame ( const View self)
Parameters
selfThe View.
Returns
This View's absolute frame in the View hierarchy, in object space.

Definition at line 1275 of file View.c.

1275 {
1276
1277 SDL_Rect frame = self->frame;
1278
1279 const View *view = self;
1280 const View *superview = view->superview;
1281 while (superview) {
1282
1283 frame.x += superview->frame.x;
1284 frame.y += superview->frame.y;
1285
1286 if (view->alignment != ViewAlignmentInternal) {
1288 frame.y += superview->padding.top;
1289 }
1290
1291 view = superview;
1292 superview = view->superview;
1293 }
1294
1295 return frame;
1296}
@ ViewAlignmentInternal
Definition: View.h:77
ViewAlignment alignment
The alignment.
Definition: View.h:149

◆ replaceSubview()

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

Replaces the specified subview with the given replacement.

Parameters
selfThe View.
subviewThe subview to replace.
replacementThe replacement subview.

Definition at line 1302 of file View.c.

1302 {
1303
1304 assert(subview);
1305 assert(replacement);
1306
1307 $(self, addSubviewRelativeTo, replacement, subview, ViewPositionAfter);
1308 $(self, removeSubview, subview);
1309}

◆ resignFirstResponder()

void resignFirstResponder ( View self)

Resigns first responder priority.

Parameters
selfThe View.

Definition at line 1315 of file View.c.

1315 {
1316
1317 if ($(self, isFirstResponder)) {
1318 $$(View, setFirstResponder, self->window, NULL);
1319 }
1320}
_Bool isFirstResponder(const View *self)
Definition: View.c:856

◆ resize()

void resize ( View self,
const SDL_Size size 
)

Resizes this View to the specified size.

Parameters
selfThe View.
sizeThe size to set.

Definition at line 1326 of file View.c.

1326 {
1327
1328 if (self->frame.w != size->w || self->frame.h != size->h) {
1329
1330 self->frame.w = clamp(size->w, self->minSize.w, self->maxSize.w);
1331 self->frame.h = clamp(size->h, self->minSize.h, self->maxSize.h);
1332
1333 self->needsLayout = true;
1334
1335 if (self->superview) {
1336 self->superview->needsLayout = true;
1337 }
1338 }
1339}
SDL_Size minSize
The minimum size this View may be resized to during layout.
Definition: View.h:211

◆ resolve()

void resolve ( View self,
Outlet outlets 
)

Resolves the given Outlets from this View's hierarchy.

Parameters
selfThe View.
outletsThe Outlets to resolve.

Definition at line 1345 of file View.c.

1345 {
1346
1347 if (outlets) {
1348 for (Outlet *outlet = outlets; outlet->identifier; outlet++) {
1349 *outlet->view = $(self, descendantWithIdentifier, outlet->identifier);
1350 assert(*outlet->view);
1351 }
1352 }
1353}
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()

void respondToEvent ( View self,
const SDL_Event *  event 
)

Responds to the specified event.

Parameters
selfThe View.
eventThe event.

Definition at line 213 of file Control.c.

213 {
214
215 Control *this = (Control *) self;
216
217 const ControlState state = this->state;
218
219 const _Bool didCaptureEvent = $(this, captureEvent, event);
220 if (didCaptureEvent) {
221
222 const Array *actions = (Array *) this->actions;
223 for (size_t i = 0; i < actions->count; i++) {
224
225 const Action *action = $(actions, objectAtIndex, i);
226 if (action->eventType == event->type) {
227 action->function(this, event, action->sender, action->data);
228 }
229 }
230 }
231
232 if (this->state != state) {
233 $(this, stateDidChange);
234 }
235
236 if (didCaptureEvent) {
237 return;
238 }
239
240 super(View, self, respondToEvent, event);
241}
static _Bool captureEvent(Control *self, const SDL_Event *event)
Definition: Control.c:277
static void stateDidChange(Control *self)
Definition: Control.c:333
ControlState
Control states, which are bit-masked.
Definition: Control.h:66
Actions bind event-driven behavior to Controls.
Definition: Action.h:50
SDL_EventType eventType
The event type.
Definition: Action.h:71
ident data
The user data.
Definition: Action.h:66
ActionFunction function
The function.
Definition: Action.h:76
ident sender
The sender.
Definition: Action.h:81
void respondToEvent(View *self, const SDL_Event *event)
Responds to the specified event.
Definition: Control.c:213

◆ select()

Set * select ( View self,
const char *  rule 
)

Resolves all descendants (including this View) that match the given Selector rule.

Parameters
selfThe View.
ruleThe Selector rule.
Returns
The Set of selected descendant Views.

◆ setFirstResponder()

void setFirstResponder ( SDL_Window *  window,
View view 
)

Sets the first responder for the given window.

Parameters
windowThe window.
viewThe View.

Definition at line 1393 of file View.c.

1393 {
1394
1395 assert(window);
1396
1397 if (view) {
1398 assert(view->window == window);
1399 SDL_SetWindowData(window, "firstResponder", view);
1400 if (MVC_LogEnabled(SDL_LOG_PRIORITY_DEBUG)) {
1401 String *desc = $((Object *) view, description);
1402 SDL_LogDebug(LOG_CATEGORY_MVC, "%s: %s\n", __func__, desc->chars);
1403 release(desc);
1404 }
1405 } else {
1406 SDL_SetWindowData(window, "firstResponder", NULL);
1407 SDL_LogDebug(LOG_CATEGORY_MVC, "%s: NULL\n", __func__);
1408 }
1409}
#define LOG_CATEGORY_MVC
Definition: Log.h:33

◆ size()

SDL_Size size ( const View self)
Parameters
selfThe View.
Returns
The size of this View's frame.

Definition at line 1415 of file View.c.

1415 {
1416 return MakeSize(self->frame.w, self->frame.h);
1417}

◆ sizeThatContains()

SDL_Size sizeThatContains ( const View self)
Parameters
selfThe View.
Returns
An SDL_Size that contains this View's subviews.
Remarks
The returned size is greater than or equal to View::sizeThatFits.

Definition at line 1423 of file View.c.

1423 {
1424
1425 const SDL_Size size = $(self, size);
1426 const SDL_Size sizeThatFits = $(self, sizeThatFits);
1427
1428 return MakeSize(max(size.w, sizeThatFits.w), max(size.h, sizeThatFits.h));
1429}
void sizeThatFits(const View *self)

◆ sizeThatFits()

SDL_Size sizeThatFits ( const View self)
Parameters
selfThe View.
Returns
An SDL_Size that fits this View's subviews.
Remarks
The default implementation of this method returns the View's current size, or an appropriate value based on this View's autoresizingMask.

Definition at line 123 of file CollectionView.c.

123 {
124
125 const CollectionView *this = (CollectionView *) self;
126
127 return $(this, naturalSize);
128}
static SDL_Size naturalSize(const CollectionView *self)

◆ sizeToContain()

void sizeToContain ( View self)

Resizes this View to contain its subviews.

Parameters
selfThe View.
See also
View::sizeThatContains(const View *)

Definition at line 1485 of file View.c.

1485 {
1486
1487 const SDL_Size size = $(self, sizeThatContains);
1488
1489 $(self, resize, &size);
1490}
void resize(View *self, const SDL_Size *size)
Resizes this View to the specified size.
Definition: View.c:1326

◆ sizeToFit()

void sizeToFit ( View self)

Resizes this View to fit its subviews.

Parameters
selfThe View.
See also
View::sizeThatFits(const View *)

Definition at line 1496 of file View.c.

1496 {
1497
1498 const SDL_Size size = $(self, sizeThatFits);
1499
1500 $(self, resize, &size);
1501}

◆ subviewWithIdentifier()

View * subviewWithIdentifier ( const View self,
const char *  identifier 
)
Parameters
selfThe View.
identifierThe identifier.
Returns
The first subview matching the given identifier.

Definition at line 1507 of file View.c.

1507 {
1508
1509 assert(identifier);
1510
1511 const Array *subviews = (Array *) self->subviews;
1512 for (size_t i = 0; i < subviews->count; i++) {
1513
1514 View *subview = $(subviews, objectAtIndex, i);
1515 if (subview->identifier) {
1516
1517 if (strcmp(identifier, subview->identifier) == 0) {
1518 return subview;
1519 }
1520 }
1521 }
1522
1523 return NULL;
1524}

◆ updateBindings()

void updateBindings ( View self)

Updates data bindings, prompting the appropriate layout changes.

Parameters
selfThe View.
Remarks
Subclasses should override this method to refresh any data sources they rely on.

Definition at line 115 of file HSVColorPicker.c.

115 {
116
117 super(View, self, updateBindings);
118
119 HSVColorPicker *this = (HSVColorPicker *) self;
120
121 $(this->hueSlider, setValue, this->hue);
122 $(this->saturationSlider, setValue, this->saturation);
123 $(this->valueSlider, setValue, this->value);
124
125 this->colorView->backgroundColor = $(this, rgbColor);
126}
static SDL_Color rgbColor(const HSVColorPicker *self)
static void setValue(ProgressBar *self, double value)
Definition: ProgressBar.c:159
The HSVColorPicker type.
void updateBindings(View *self)
Updates data bindings, prompting the appropriate layout changes.

◆ viewport()

SDL_Rect viewport ( const View self)
Parameters
selfThe View.
Returns
The OpenGL viewport for this View.

Definition at line 1545 of file View.c.

1545 {
1546
1547 assert(self->window);
1548
1549 const SDL_Rect frame = $(self, renderFrame);
1550
1551 return MVC_TransformToWindow(self->window, &frame);
1552}
SDL_Rect MVC_TransformToWindow(SDL_Window *window, const SDL_Rect *rect)
Transforms the specified rectangle to normalized device coordinates in window.
Definition: Window.c:28

◆ viewWithCharacters()

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

Instantiates a View initialized with the given null-terminated JSON C string.

Parameters
charsA null-terminated JSON C string describing a View.
outletsAn optional array of Outlets to resolve.
Returns
The initialized View, or NULL on error.

Definition at line 1558 of file View.c.

1558 {
1559
1560 Data *data = $$(Data, dataWithConstMemory, (ident) chars, strlen(chars));
1561
1562 View *view = $$(View, viewWithData, data, outlets);
1563
1564 release(data);
1565
1566 return view;
1567}
View * viewWithData(const Data *data, Outlet *outlets)
Instantiates a View initialized with the contents of data.
Definition: View.c:1573

◆ viewWithData()

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

Instantiates a View initialized with the contents of data.

Parameters
dataA Data containing JSON describing a View.
outletsAn optional array of Outlets to resolve.
Returns
The initialized View, or NULL on error.

Definition at line 1573 of file View.c.

1573 {
1574
1575 Dictionary *dictionary = $$(JSONSerialization, objectFromData, data, 0);
1576
1577 View *view = $$(View, viewWithDictionary, dictionary, outlets);
1578
1579 release(dictionary);
1580
1581 return view;
1582}
View * viewWithDictionary(const Dictionary *dictionary, Outlet *outlets)
Instantiates a View initialized with the attributes described in dictionary.
Definition: View.c:1588

◆ viewWithDictionary()

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

Instantiates a View initialized with the attributes described in dictionary.

Parameters
dictionaryA Dictionary describing a View.
outletsAn optional array of Outlets to resolve.
Returns
The initialized View, or NULL on error.
See also
View::initWithDictionary(View *, const Dictionary *, Outlet *outlets)

Definition at line 1588 of file View.c.

1588 {
1589
1590 View *view = NULL;
1591
1592 BindInlet(&MakeInlet(NULL, InletTypeView, &view, NULL), dictionary);
1593
1594 $(view, resolve, outlets);
1595
1596 return view;
1597}
#define BindInlet(inlet, obj)
Binds the Inlet to obj by invoking the appropriate InletBinding function.
Definition: View+JSON.h:244
void resolve(View *self, Outlet *outlets)
Resolves the given Outlets from this View's hierarchy.
Definition: View.c:1345

◆ viewWithResource()

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

Instantiates a View initialized with the JSON data in resource.

Parameters
resourceA Resource containing JSON describing a View.
outletsAn optional array of Outlets to resolve.
Returns
The initialized View, or NULL on error.
See also
View::initWithData(View *, const Data *, Outlet *outlets)

Definition at line 1603 of file View.c.

1603 {
1604
1605 assert(resource);
1606
1607 return $$(View, viewWithData, resource->data, outlets);
1608}

◆ viewWithResourceName()

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

Instantiates a View initialized with the JSON Resource with the specified name.

Parameters
nameThe name of a JSON Resource describing a View.
outletsAn optional array of Outlets to resolve.
Returns
The initialized View, or NULL on error.
See also
View::initWithResource(View *, const Dictionary *, Outlet *outlets)

Definition at line 1614 of file View.c.

1614 {
1615
1616 Resource *resource = $$(Resource, resourceWithName, name);
1617
1618 View *view = $$(View, viewWithResource, resource, outlets);
1619
1620 release(resource);
1621
1622 return view;
1623}
View * viewWithResource(const Resource *resource, Outlet *outlets)
Instantiates a View initialized with the JSON data in resource.
Definition: View.c:1603

◆ visibleSubviews()

Array * visibleSubviews ( const View self)
Parameters
selfThe View.
Returns
An Array of this View's visible subviews.
Remarks
The returned Array excludes that specify ViewAlignmentInternal.

Definition at line 78 of file PageView.c.

78 {
79 return $$(Array, arrayWithArray, (Array *) self->subviews);
80}

◆ warn()

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

Appends a warning for this View.

Parameters
selfThe View.
fmtThe format string.

Definition at line 1647 of file View.c.

1647 {
1648 va_list args;
1649 va_start(args, fmt);
1650
1651 String *warning = $(alloc(String), initWithVaList, fmt, args);
1652 assert(warning);
1653
1654 va_end(args);
1655
1656 $(self->warnings, addObject, warning);
1657 release(warning);
1658}

◆ willMoveToWindow()

void willMoveToWindow ( View self,
SDL_Window *  window 
)

Informs this View that it will be added to the View hierarchy for the given window.

Parameters
selfThe View.
windowThe window, or NULL if this View will be removed from the window.

Definition at line 1664 of file View.c.

1664 {
1665
1666 if (self->window) {
1667 $(self, resignFirstResponder);
1668 $(self, detachStylesheet, self->window);
1669 }
1670}
void detachStylesheet(View *self, SDL_Window *window)
Detaches this View's Stylesheet from the Theme associated with the given window.
Definition: View.c:517
void resignFirstResponder(View *self)
Resigns first responder priority.
Definition: View.c:1315

Field Documentation

◆ alignment

ViewAlignment View::alignment

The alignment.

Definition at line 149 of file View.h.

◆ autoresizingMask

int View::autoresizingMask

The ViewAutoresizing bitmask.

Definition at line 154 of file View.h.

◆ backgroundColor

SDL_Color View::backgroundColor

The background color.

Definition at line 159 of file View.h.

◆ borderColor

SDL_Color View::borderColor

The border color.

Definition at line 164 of file View.h.

◆ borderWidth

int View::borderWidth

The border width.

Definition at line 169 of file View.h.

◆ classNames

MutableSet* View::classNames

The class names.

See also
Style

Definition at line 175 of file View.h.

◆ clipsSubviews

_Bool View::clipsSubviews

If true, subviews will be clipped to this View's frame.

Definition at line 180 of file View.h.

◆ computedStyle

Style* View::computedStyle

The computed Style of this View.

Definition at line 185 of file View.h.

◆ frame

SDL_Rect View::frame

The frame, relative to the superview.

Definition at line 190 of file View.h.

◆ hidden

_Bool View::hidden

If true, this View is not drawn.

Definition at line 195 of file View.h.

◆ identifier

char* View::identifier

An optional identifier.

Remarks
Identifiers are commonly used to resolve Outlets when loading Views via JSON.

Definition at line 201 of file View.h.

◆ interface

ViewInterface* View::interface
protected

The interface.

Definition at line 144 of file View.h.

◆ maxSize

SDL_Size View::maxSize

The maximum size this View may be resized to during layout.

Definition at line 206 of file View.h.

◆ minSize

SDL_Size View::minSize

The minimum size this View may be resized to during layout.

Definition at line 211 of file View.h.

◆ needsApplyTheme

_Bool View::needsApplyTheme

If true, this View will apply the Theme before it is drawn.

Definition at line 216 of file View.h.

◆ needsLayout

_Bool View::needsLayout

If true, this View will layout its subviews before it is drawn.

Definition at line 221 of file View.h.

◆ nextResponder

View* View::nextResponder

The next responder, or event handler, in the chain.

Remarks
By default, Views propagate events to their superview. If this member is not NULL, events will instead be propagated to this View.

Definition at line 228 of file View.h.

◆ object

Object View::object

The superclass.

Definition at line 138 of file View.h.

◆ padding

ViewPadding View::padding

The padding.

Definition at line 233 of file View.h.

◆ style

Style* View::style

The element-level Style of this View.

Remarks
Attributes in this Style are local to this View, and override any Attributes matched via Selector. That is, it is always the last Style added to the computed Style.

Definition at line 240 of file View.h.

◆ stylesheet

Stylesheet* View::stylesheet

An optional Stylesheet.

Remarks
If set, this Stylesheet is added to or removed from the current Theme when this View is added to or removed from a valid View hierarchy.

Definition at line 247 of file View.h.

◆ subviews

MutableArray* View::subviews

The immediate subviews.

Definition at line 252 of file View.h.

◆ superview

View* View::superview

The super View.

Remarks
This reference is not retained.

Definition at line 258 of file View.h.

◆ viewController

ViewController* View::viewController

The ViewController.

Remarks
This is NULL unless the View is the immediate view of a ViewController.

Definition at line 264 of file View.h.

◆ warnings

MutableArray* View::warnings

The warnings this View generated.

Remarks
These are optionally displayed by the DebugViewController.

Definition at line 270 of file View.h.

◆ window

SDL_Window* View::window

The window.

Remarks
This is NULL until the View has been added to a WindowController.

Definition at line 276 of file View.h.


The documentation for this struct was generated from the following files: