33#define _Class _CollectionView
44 release(this->contentView);
46 release(this->scrollView);
91 const Array *items = (Array *) this->items;
92 for (
size_t i = 0; i < items->count; i++) {
101 switch (this->axis) {
103 x += this->itemSize.w + this->itemSpacing.w;
104 if (x + this->itemSize.w >
bounds.w) {
105 y += this->itemSize.h + this->itemSpacing.h;
110 y += this->itemSize.h + this->itemSpacing.h;
111 if (y + this->itemSize.h >
bounds.h) {
112 x += this->itemSize.w + this->itemSpacing.w;
130#pragma mark - Control
137 if (event->type == SDL_MOUSEBUTTONUP) {
144 const SDL_Point point = {
145 .x =
event->button.x,
164 if (SDL_GetModState() & (KMOD_CTRL | KMOD_GUI)) {
177 if (this->delegate.didModifySelection) {
195#pragma mark - CollectionView
258 const int rows = max(1, frame.h / itemHeight);
259 const int cols = max(1, frame.w / itemWidth);
261 const int x = point->x - frame.x;
262 const int y = point->y - frame.y;
264 const int row = y / itemHeight;
265 const int col = x / itemWidth;
268 switch (self->
axis) {
270 index = row * cols + col;
273 index = col * rows + row;
277 if (index < (
int) self->
items->array.count) {
278 return $(alloc(IndexPath), initWithIndex, index);
291 const ssize_t index = $((Array *) self->
items, indexOfObject, (ident) item);
293 return $(alloc(IndexPath), initWithIndex, index);
308 self->
items = $$(MutableArray, array);
334 const Array *items = (Array *) self->
items;
335 const size_t index = $(indexPath, indexAtPosition, 0);
337 if (index < items->count) {
338 return $(items, objectAtIndex, index);
360 switch (self->
axis) {
372 const int rows = ceilf(self->
items->array.count / (
float) itemsPerRow);
388 const int cols = ceilf(self->
items->array.count / (
float) itemsPerCol);
415 $(self->
items, removeAllObjects);
418 for (
size_t i = 0; i < numberOfItems; i++) {
420 IndexPath *indexPath = $(alloc(IndexPath), initWithIndex, i);
425 $(self->
items, addObject, item);
432 ((
View *) self)->needsLayout =
true;
456 MutableArray *array = $$(MutableArray, array);
458 const Array *items = (Array *) self->
items;
459 for (
size_t i = 0; i < items->count; i++) {
465 $(array, addObject, indexPath);
471 return (Array *) array;
507#pragma mark - Class lifecycle
514 ((ObjectInterface *) clazz->interface)->dealloc =
dealloc;
516 ((ViewInterface *) clazz->interface)->applyStyle =
applyStyle;
517 ((ViewInterface *) clazz->interface)->init =
init;
519 ((ViewInterface *) clazz->interface)->sizeThatFits =
sizeThatFits;
521 ((ControlInterface *) clazz->interface)->captureEvent =
captureEvent;
523 ((CollectionViewInterface *) clazz->interface)->deselectAll =
deselectAll;
526 ((CollectionViewInterface *) clazz->interface)->indexPathForItem =
indexPathForItem;
528 ((CollectionViewInterface *) clazz->interface)->initWithFrame =
initWithFrame;
529 ((CollectionViewInterface *) clazz->interface)->itemAtIndexPath =
itemAtIndexPath;
530 ((CollectionViewInterface *) clazz->interface)->naturalSize =
naturalSize;
531 ((CollectionViewInterface *) clazz->interface)->reloadData =
reloadData;
532 ((CollectionViewInterface *) clazz->interface)->selectAll =
selectAll;
547 clazz = _initialize(&(
const ClassDef) {
548 .name =
"CollectionView",
552 .interfaceSize =
sizeof(CollectionViewInterface),
static void selectItemsAtIndexPaths_enumerate(const Array *array, ident obj, ident data)
ArrayEnumerator for item selection.
const EnumName CollectionViewAxisNames[]
static void deselectAll_enumerate(const Array *array, ident obj, ident data)
ArrayEnumerator for all item deselection.
static void dealloc(Object *self)
static void selectAll_enumerate(const Array *array, ident obj, ident data)
ArrayEnumerator for all item selection.
static void initialize(Class *clazz)
static void deselectItemsAtIndexPaths_enumerate(const Array *array, ident obj, ident data)
ArrayEnumerator for item deselection.
static void reloadData_removeItems(const Array *array, ident obj, ident data)
ArrayEnumerator to remove CollectionItemViews from the collection's contentView.
@ ControlSelectionMultiple
#define MakeSize(w, h)
Creates an SDL_Size with the given dimensions.
#define MakeInlets(...)
Creates a null-termianted array of Inlets.
#define MakeInlet(name, type, dest, data)
Creates an Inlet with the specified parameters.
#define MakePadding(top, right, bottom, left)
Creates a ViewPadding with the given dimensions.
@ CollectionViewAxisHorizontal
@ CollectionViewAxisVertical
Box * initWithFrame(Box *self, const SDL_Rect *frame)
Initializes this Box with the given frame.
CollectionViewItems are a visual representation of an item within a CollectionView.
void setSelected(CollectionItemView *self, _Bool isSelected)
Sets the selected state of this item.
_Bool isSelected
True when this item is selected, false otherwise.
size_t(* numberOfItems)(const CollectionView *collectionView)
CollectionItemView *(* itemForObjectAtIndexPath)(const CollectionView *collectionView, const IndexPath *indexPath)
Called by the CollectionView to instantiate items.
CollectionViews display items in a grid.
void deselectItemsAtIndexPaths(CollectionView *self, const Array *indexPaths)
Deselects the items at the given index paths.
SDL_Size itemSize
The item size.
Array * selectionIndexPaths(const CollectionView *self)
CollectionViewAxis axis
The layout axis.
IndexPath * indexPathForItemAtPoint(const CollectionView *self, const SDL_Point *point)
CollectionItemView * itemAtIndexPath(const CollectionView *self, const IndexPath *indexPath)
CollectionViewDelegate delegate
The delegate.
IndexPath * indexPathForItem(const CollectionView *self, const CollectionItemView *item)
void deselectAll(CollectionView *self)
Deselects all items in this CollectionView.
void reloadData(CollectionView *self)
Reloads this CollectionView's visible items.
Class * _CollectionView(void)
The CollectionView archetype.
MutableArray * items
The items.
void selectItemsAtIndexPaths(CollectionView *self, const Array *indexPaths)
Selects the items at the given index paths.
CollectionViewDataSource dataSource
The data source.
void selectItemAtIndexPath(CollectionView *self, const IndexPath *indexPath)
Selects the item at the given index path.
SDL_Size naturalSize(const CollectionView *self)
void selectAll(CollectionView *self)
Selects all items in this CollectionView.
ScrollView * scrollView
The scroll view.
void deselectItemAtIndexPath(CollectionView *self, const IndexPath *indexPath)
Deselects the item at the given index path.
CollectionView * init(CollectionView *self, const SDL_Rect *frame)
Initializes this CollectionView with the specified frame and style.
SDL_Size itemSpacing
The item spacing.
View * contentView
The content view.
Controls are Views which capture events and dispatch Actions.
_Bool captureEvent(Control *self, const SDL_Event *event)
Captures a given event, potentially altering the state of this Control.
Class * _Control(void)
The Control archetype.
_Bool isHighlighted(const Control *self)
ControlSelection selection
The ControlSelection.
SDL_Size size(const Image *self)
Inlets enable inbound data binding of View attributes through JSON.
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
SDL_Rect bounds(const View *self)
_Bool bind(View *self, const Inlet *inlets, const Dictionary *dictionary)
Performs data binding for the Inlets described in dictionary.
void invalidateStyle(View *self)
Invalidates the computed Style for this View and its descendants.
void addSubview(View *self, View *subview)
Adds a subview to this view, to be drawn above its siblings.
void addClassName(View *self, const char *className)
Adds the given class name to this View.
void applyStyle(View *self, const Style *style)
Applies the given Style to this View.
_Bool didReceiveEvent(const View *self, const SDL_Event *event)
void sizeThatFits(const View *self)
SDL_Rect renderFrame(const View *self)
layoutSubviews(View *self)
Performs layout for this View's immediate subviews.
SDL_Rect frame
The frame, relative to the superview.
void removeSubview(View *self, View *subview)
Removes the given subview from this View.
Spacing applied to the inside of a View's frame.