27#include <Objectively/String.h>
31#define _Class _TableView
42 memset(&this->delegate, 0,
sizeof(this->delegate));
44 release(this->columns);
45 release(this->contentView);
46 release(this->headerView);
48 release(this->scrollView);
60 const String *identifier = $((Dictionary *) obj, objectForKeyPath,
"identifier");
78 const Array *columns = $(dictionary, objectForKeyPath,
"columns");
100 View *scrollView = (
View *) this->scrollView;
101 View *headerView = (
View *) this->headerView;
103 SDL_Rect frame = $(self,
bounds);
105 if (headerView->
hidden ==
false) {
113 scrollView->
frame = frame;
129#pragma mark - Control
139 if (event->type == SDL_EVENT_MOUSE_BUTTON_UP) {
143 const SDL_Point point = {
144 .x =
event->button.x,
159 const SDL_Point point = {
160 .x =
event->button.x,
164 const ssize_t index = $(
this,
rowAtPoint, &point);
166 const Array *rows = (Array *) this->rows;
167 if (index > -1 && index < (ssize_t) rows->count) {
171 switch (this->control.selection) {
181 if (SDL_GetModState() & (SDL_KMOD_CTRL | SDL_KMOD_GUI)) {
194 if (this->delegate.didSelectRowsAtIndexes) {
212#pragma mark - TableView
222 $(self->
columns, addObject, column);
248 if (SDL_PointInRect(point, &frame)) {
251 const Array *columns = (Array *) self->
columns;
253 assert(cells->count == columns->count);
255 for (
size_t i = 0; i < cells->count; i++) {
257 const View *cell = $(cells, objectAtIndex, i);
261 return $(columns, objectAtIndex, i);
277 const Array *columns = (Array *) self->
columns;
278 for (
size_t i = 0; i < columns->count; i++) {
280 TableColumn *column = $(columns, objectAtIndex, i);
281 if (strcmp(identifier, column->
identifier) == 0) {
310 const Array *rows = (Array *) self->
rows;
311 if (index < rows->count) {
325 for (
size_t i = 0; i < indexes->count; i++) {
339 self->
columns = $$(Array, array);
342 self->
rows = $$(Array, array);
351 assert(self->contentView);
356 assert(self->scrollView);
379 size.w += this->padding.left + this->padding.right;
380 size.h += this->padding.top + this->padding.bottom;
406 const Array *columns = (Array *) self->
columns;
407 for (
size_t i = 0; i < columns->count; i++) {
409 const TableColumn *column = $(columns, objectAtIndex, i);
414 for (
size_t i = 0; i < numberOfRows; i++) {
419 for (
size_t j = 0; j < columns->count; j++) {
420 const TableColumn *column = $(columns, objectAtIndex, j);
431 $(self->
rows, addObject, row);
453 $(self->
columns, removeObject, column);
465 if (SDL_PointInRect(point, &scrollFrame)) {
467 const Array *rows = (Array *) self->
rows;
468 for (
size_t i = 0; i < rows->count; i++) {
470 const View *row = $(rows, objectAtIndex, i);
501 size_t indexes[self->
rows->count];
504 const Array *rows = (Array *) self->
rows;
505 for (
size_t i = 0; i < rows->count; i++) {
509 indexes[count++] = i;
513 return $(alloc(IndexSet), initWithIndexes, indexes, count);
522 const Array *rows = (Array *) self->
rows;
523 if (index < rows->count) {
539 for (
size_t i = 0; i < indexes->count; i++) {
559 assert($((Array *) self->
columns, containsObject, column));
575#pragma mark - Class lifecycle
582 ((ObjectInterface *) clazz->interface)->dealloc =
dealloc;
585 ((ViewInterface *) clazz->interface)->init =
init;
587 ((ViewInterface *) clazz->interface)->sizeThatFits =
sizeThatFits;
589 ((ControlInterface *) clazz->interface)->captureEvent =
captureEvent;
591 ((TableViewInterface *) clazz->interface)->addColumn =
addColumn;
593 ((TableViewInterface *) clazz->interface)->columnAtPoint =
columnAtPoint;
595 ((TableViewInterface *) clazz->interface)->deselectAll =
deselectAll;
598 ((TableViewInterface *) clazz->interface)->initWithFrame =
initWithFrame;
600 ((TableViewInterface *) clazz->interface)->reloadData =
reloadData;
601 ((TableViewInterface *) clazz->interface)->removeColumn =
removeColumn;
602 ((TableViewInterface *) clazz->interface)->rowAtPoint =
rowAtPoint;
604 ((TableViewInterface *) clazz->interface)->selectAll =
selectAll;
605 ((TableViewInterface *) clazz->interface)->selectRowAtIndex =
selectRowAtIndex;
607 ((TableViewInterface *) clazz->interface)->setSortColumn =
setSortColumn;
619 clazz = _initialize(&(
const ClassDef) {
623 .interfaceOffset = offsetof(
TableView, interface),
624 .interfaceSize =
sizeof(TableViewInterface),
static void setSelected(CollectionItemView *self, bool isSelected)
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 contentSize(const Panel *self)
static TableColumn * initWithIdentifier(TableColumn *self, const char *identifier)
static void removeCell(TableRowView *self, TableCellView *cell)
static void addCell(TableRowView *self, TableCellView *cell)
static void removeAllCells(TableRowView *self)
static void setSortColumn(TableView *self, TableColumn *column)
static void deselectAll(TableView *self)
static void selectRowAtIndex(TableView *self, size_t index)
static TableView * initWithFrame(TableView *self, const SDL_Rect *frame)
static View * init(View *self)
static void reloadData_removeRows(const Array *array, ident obj, ident data)
ArrayEnumerator to remove TableRowViews from the table's contentView.
static void awakeWithDictionary(View *self, const Dictionary *dictionary)
static void deselectRowsAtIndexes(TableView *self, const IndexSet *indexes)
static void selectRowsAtIndexes(TableView *self, const IndexSet *indexes)
static IndexSet * selectedRowIndexes(const TableView *self)
static SDL_Size sizeThatFits(const View *self)
static bool captureEvent(Control *self, const SDL_Event *event)
static TableColumn * columnWithIdentifier(const TableView *self, const char *identifier)
static SDL_Size naturalSize(const TableView *self)
static void selectAll(TableView *self)
static void deselectAll_enumerate(const Array *array, ident obj, ident data)
ArrayEnumerator for all Row deselection.
static void addColumnWithIdentifier(TableView *self, const char *identifier)
static void dealloc(Object *self)
static void addColumn(TableView *self, TableColumn *column)
static ssize_t rowAtPoint(const TableView *self, const SDL_Point *point)
static void awakeWithDictionary_columns(const Array *array, ident obj, ident data)
ArrayEnumerator for awaking TableColumns.
static void removeColumn(TableView *self, TableColumn *column)
static void selectAll_enumerate(const Array *array, ident obj, ident data)
ArrayEnumerator for all row selection.
static void deselectRowAtIndex(TableView *self, size_t index)
static void initialize(Class *clazz)
static void reloadData(TableView *self)
static void layoutSubviews(View *self)
static TableColumn * columnAtPoint(const TableView *self, const SDL_Point *point)
TableViews provide sortable, tabular presentations of data.
static void addClassName(View *self, const char *className)
static void layoutIfNeeded(View *self)
static bool didReceiveEvent(const View *self, const SDL_Event *event)
static SDL_Rect renderFrame(const View *self)
static void enumerate(View *self, ViewEnumerator enumerator, ident data)
static bool containsPoint(const View *self, const SDL_Point *point)
static SDL_Rect bounds(const View *self)
Controls are Views which capture and respond to events.
StackViews are containers that manage the arrangement of their subviews.
Each row in a TableView is comprised of TableCellViews.
Columns provide alignment, spacing and sorting hints for TableView instances.
char * identifier
The identifier.
TableHeaderCellView * headerCell
The header cell.
Order order
The sort order.
bool isSelected
True when this row is selected, false otherwise.
size_t(* numberOfRows)(const TableView *tableView)
void(* didSetSortColumn)(TableView *tableView)
Called by the TableView when the sort column or order changes.
TableCellView *(* cellForColumnAndRow)(const TableView *tableView, const TableColumn *column, size_t row)
Called by the TableView to instantiate cells.
TableViews provide sortable, tabular presentations of data.
Control control
The superclass.
ScrollView * scrollView
The scroll view.
TableViewDelegate delegate
The delegate.
TableColumn * sortColumn
The column to sort by.
TableViewDataSource dataSource
The data source.
SDL_Size naturalSize(const TableView *self)
Array * columns
The column definitions.
StackView * contentView
The content View.
TableHeaderView * headerView
The header.
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
bool needsLayout
If true, this View will layout its subviews before it is drawn.
char * identifier
An optional identifier.
layoutSubviews(View *self)
Performs layout for this View's immediate subviews.
SDL_Rect frame
The frame, relative to the superview.
bool hidden
If true, this View is not drawn.