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++) {
104 switch (this->axis) {
106 x += this->itemSize.w + this->itemSpacing.w;
107 if (x + this->itemSize.w >
bounds.w) {
108 y += this->itemSize.h + this->itemSpacing.h;
113 y += this->itemSize.h + this->itemSpacing.h;
114 if (y + this->itemSize.h >
bounds.h) {
115 x += this->itemSize.w + this->itemSpacing.w;
123#pragma mark - Control
130 if (event->type == SDL_EVENT_MOUSE_BUTTON_UP) {
137 const SDL_Point point = {
138 .x =
event->button.x,
157 if (SDL_GetModState() & (SDL_KMOD_CTRL | SDL_KMOD_GUI)) {
170 if (this->delegate.didModifySelection) {
188#pragma mark - CollectionView
251 const int rows = max(1, frame.h / itemHeight);
252 const int cols = max(1, frame.w / itemWidth);
254 const int x = point->x - frame.x;
255 const int y = point->y - frame.y;
257 const int row = y / itemHeight;
258 const int col = x / itemWidth;
261 switch (self->
axis) {
263 index = row * cols + col;
266 index = col * rows + row;
270 if (index < (
int) self->
items->count) {
271 return $(alloc(IndexPath), initWithIndex, index);
284 const ssize_t index = $((Array *) self->
items, indexOfObject, (ident) item);
286 return $(alloc(IndexPath), initWithIndex, index);
300 self->
items = $$(Array, array);
326 const Array *items = (Array *) self->
items;
327 const size_t index = $(indexPath, indexAtPosition, 0);
329 if (index < items->count) {
330 return $(items, objectAtIndex, index);
351 SDL_Size scrollViewSize;
357 scrollViewSize = $(scrollView,
size);
360 switch (self->
axis) {
363 int w = scrollViewSize.w;
372 const int rows = ceilf(self->
items->count / (
float) itemsPerRow);
379 int h = scrollViewSize.h;
388 const int cols = ceilf(self->
items->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);
456 Array *array = $$(Array, 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;
520 ((ControlInterface *) clazz->interface)->captureEvent =
captureEvent;
522 ((CollectionViewInterface *) clazz->interface)->deselectAll =
deselectAll;
525 ((CollectionViewInterface *) clazz->interface)->indexPathForItem =
indexPathForItem;
527 ((CollectionViewInterface *) clazz->interface)->initWithFrame =
initWithFrame;
529 ((CollectionViewInterface *) clazz->interface)->naturalSize =
naturalSize;
530 ((CollectionViewInterface *) clazz->interface)->reloadData =
reloadData;
531 ((CollectionViewInterface *) clazz->interface)->selectAll =
selectAll;
546 clazz = _initialize(&(
const ClassDef) {
547 .name =
"CollectionView",
550 .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 bool didReceiveEvent(const View *self, const SDL_Event *event)
static void invalidateStyle(View *self)
static void setNeedsLayout(View *self)
static SDL_Size sizeThatContains(const View *self)
static void layoutWithSize(View *self, const SDL_Size *size)
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)
Arranges this View's immediate subviews within its (already final) frame.
SDL_Rect frame
The frame, relative to the superview.
Spacing applied to the inside of a View's frame.