34#define _Class _CollectionView
45 memset(&this->delegate, 0,
sizeof(this->delegate));
47 release(this->contentView);
49 release(this->scrollView);
71 $(self, bind, inlets, (Dictionary *) style->
attributes);
94 const Array *items = (Array *) this->items;
95 for (
size_t i = 0; i < items->count; i++) {
105 switch (this->axis) {
107 x += this->itemSize.w + this->itemSpacing.w;
108 if (x + this->itemSize.w >
bounds.w) {
109 y += this->itemSize.h + this->itemSpacing.h;
114 y += this->itemSize.h + this->itemSpacing.h;
115 if (y + this->itemSize.h >
bounds.h) {
116 x += this->itemSize.w + this->itemSpacing.w;
124#pragma mark - Control
131 if (event->type == SDL_EVENT_MOUSE_BUTTON_UP) {
138 const SDL_Point point = {
139 .x =
event->button.x,
158 if (SDL_GetModState() & (SDL_KMOD_CTRL | SDL_KMOD_GUI)) {
171 if (this->delegate.didModifySelection) {
189#pragma mark - CollectionView
252 const int rows = max(1, frame.h / itemHeight);
253 const int cols = max(1, frame.w / itemWidth);
255 const int x = point->x - frame.x;
256 const int y = point->y - frame.y;
258 const int row = y / itemHeight;
259 const int col = x / itemWidth;
262 switch (self->
axis) {
264 index = row * cols + col;
267 index = col * rows + row;
271 if (index < (
int) self->
items->count) {
272 return $(alloc(IndexPath), initWithIndex, index);
285 const ssize_t index = $((Array *) self->
items, indexOfObject, (ident) item);
287 return $(alloc(IndexPath), initWithIndex, index);
301 self->
items = $$(Array, array);
327 const Array *items = (Array *) self->
items;
328 const size_t index = $(indexPath, indexAtPosition, 0);
330 if (index < items->count) {
331 return $(items, objectAtIndex, index);
352 SDL_Size scrollViewSize;
358 scrollViewSize = $(scrollView,
size);
361 switch (self->
axis) {
364 int w = scrollViewSize.w;
373 const int rows = ceilf(self->
items->count / (
float) itemsPerRow);
380 int h = scrollViewSize.h;
389 const int cols = ceilf(self->
items->count / (
float) itemsPerCol);
416 $(self->
items, removeAllObjects);
419 for (
size_t i = 0; i < numberOfItems; i++) {
421 IndexPath *indexPath = $(alloc(IndexPath), initWithIndex, i);
426 $(self->
items, addObject, item);
433 ((
View *) self)->needsLayout =
true;
457 Array *array = $$(Array, array);
459 const Array *items = (Array *) self->
items;
460 for (
size_t i = 0; i < items->count; i++) {
466 $(array, addObject, indexPath);
472 return (Array *) array;
508#pragma mark - Class lifecycle
515 ((ObjectInterface *) clazz->interface)->dealloc =
dealloc;
517 ((ViewInterface *) clazz->interface)->applyStyle =
applyStyle;
518 ((ViewInterface *) clazz->interface)->init =
init;
521 ((ControlInterface *) clazz->interface)->captureEvent =
captureEvent;
523 ((CollectionViewInterface *) clazz->interface)->deselectAll =
deselectAll;
526 ((CollectionViewInterface *) clazz->interface)->indexPathForItem =
indexPathForItem;
528 ((CollectionViewInterface *) clazz->interface)->initWithFrame =
initWithFrame;
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 setSelected(CollectionItemView *self, bool isSelected)
static void selectItemsAtIndexPaths_enumerate(const Array *array, ident obj, ident data)
ArrayEnumerator for item selection.
static void selectAll(CollectionView *self)
static void deselectItemAtIndexPath(CollectionView *self, const IndexPath *indexPath)
static IndexPath * indexPathForItem(const CollectionView *self, const CollectionItemView *item)
static View * init(View *self)
static CollectionItemView * itemAtIndexPath(const CollectionView *self, const IndexPath *indexPath)
static CollectionView * initWithFrame(CollectionView *self, const SDL_Rect *frame)
static void applyStyle(View *self, const Style *style)
Class * _CollectionView(void)
static bool captureEvent(Control *self, const SDL_Event *event)
const EnumName CollectionViewAxisNames[]
static void deselectAll_enumerate(const Array *array, ident obj, ident data)
ArrayEnumerator for all item deselection.
static void deselectItemsAtIndexPaths(CollectionView *self, const Array *indexPaths)
static Array * selectionIndexPaths(const CollectionView *self)
static IndexPath * indexPathForItemAtPoint(const CollectionView *self, const SDL_Point *point)
static void selectItemsAtIndexPaths(CollectionView *self, const Array *indexPaths)
static void dealloc(Object *self)
static SDL_Size naturalSize(const CollectionView *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 layoutSubviews(View *self)
static void selectItemAtIndexPath(CollectionView *self, const IndexPath *indexPath)
static void deselectAll(CollectionView *self)
static void reloadData(CollectionView *self)
static void reloadData_removeItems(const Array *array, ident obj, ident data)
ArrayEnumerator to remove CollectionItemViews from the collection's contentView.
static bool isHighlighted(const Control *self)
@ ControlSelectionMultiple
static SDL_Size size(const Image *self)
static void removeSubview(View *self, View *subview)
static void addSubview(View *self, View *subview)
static SDL_Size sizeThatFits(const View *self)
#define MakeInlets(...)
Creates a null-termianted array of Inlets.
#define MakeInlet(name, type, dest, data)
Creates an Inlet with the specified parameters.
static void addClassName(View *self, const char *className)
static void resize(View *self, const SDL_Size *size)
static void layoutIfNeeded(View *self)
static bool didReceiveEvent(const View *self, const SDL_Event *event)
static void invalidateStyle(View *self)
static SDL_Size sizeThatContains(const View *self)
static SDL_Rect renderFrame(const View *self)
static void enumerate(View *self, ViewEnumerator enumerator, ident data)
static SDL_Rect bounds(const View *self)
#define MakePadding(top, right, bottom, left)
Creates a ViewPadding with the given dimensions.
@ ViewAutoresizingContain
@ CollectionViewAxisHorizontal
@ CollectionViewAxisVertical
CollectionViewItems are a visual representation of an item within a CollectionView.
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.
SDL_Size itemSize
The item size.
CollectionViewAxis axis
The layout axis.
CollectionItemView * itemAtIndexPath(const CollectionView *self, const IndexPath *indexPath)
CollectionViewDelegate delegate
The delegate.
CollectionViewDataSource dataSource
The data source.
ScrollView * scrollView
The scroll view.
SDL_Size itemSpacing
The item spacing.
View * contentView
The content view.
Controls are Views which capture and respond to events.
ControlSelection selection
The ControlSelection.
Inlets enable inbound data binding of View attributes through JSON.
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
int autoresizingMask
The ViewAutoresizing bitmask.
layoutSubviews(View *self)
Performs layout for this View's immediate subviews.
SDL_Rect frame
The frame, relative to the superview.
Spacing applied to the inside of a View's frame.