Started the OS X uiTable implementation.
This commit is contained in:
parent
b21ec6cf6b
commit
2f08ec683a
|
@ -34,6 +34,7 @@ list(APPEND _LIBUI_SOURCES
|
||||||
darwin/spinbox.m
|
darwin/spinbox.m
|
||||||
darwin/stddialogs.m
|
darwin/stddialogs.m
|
||||||
darwin/tab.m
|
darwin/tab.m
|
||||||
|
darwin/table.m
|
||||||
darwin/text.m
|
darwin/text.m
|
||||||
darwin/util.m
|
darwin/util.m
|
||||||
darwin/window.m
|
darwin/window.m
|
||||||
|
|
|
@ -0,0 +1,239 @@
|
||||||
|
// 21 june 2016
|
||||||
|
#import "uipriv_darwin.h"
|
||||||
|
|
||||||
|
@interface tableModel : NSObject<NSTableViewDataSource, NSTableViewDelegate> {
|
||||||
|
uiTableModel *libui_m;
|
||||||
|
}
|
||||||
|
- (id)initWithModel:(uiTableModel *)m;
|
||||||
|
@end
|
||||||
|
|
||||||
|
enum {
|
||||||
|
partText,
|
||||||
|
};
|
||||||
|
|
||||||
|
@interface tablePart : NSObject
|
||||||
|
@property int type;
|
||||||
|
@property int mainColumn;
|
||||||
|
@property int expand;
|
||||||
|
- (NSView *)mkView:(uiTableModel *)m row:(int)row;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface tableColumn : NSTableColumn
|
||||||
|
@property uiTableColumn *libui_col;
|
||||||
|
@end
|
||||||
|
|
||||||
|
struct uiTableModel {
|
||||||
|
uiTableModelHandler *mh;
|
||||||
|
tableModel *m;
|
||||||
|
NSMutableArray *tables;
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO better memory management for this
|
||||||
|
// note how expand is part of this
|
||||||
|
struct uiTableCellPart {
|
||||||
|
tablePart *part;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct uiTableColumn {
|
||||||
|
NSMutableArray *parts;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct uiTable {
|
||||||
|
uiDarwinControl c;
|
||||||
|
NSScrollView *sv;
|
||||||
|
NSTableView *tv;
|
||||||
|
};
|
||||||
|
|
||||||
|
@implementation tableModel
|
||||||
|
|
||||||
|
- (id)initWithModel:(uiTableModel *)m
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self)
|
||||||
|
self->libui_m = m;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tv
|
||||||
|
{
|
||||||
|
uiTableModelHandler *mh = self->libui_m->mh;
|
||||||
|
|
||||||
|
return (*(mh->NumRows))(mh, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
// these are according to Interface Builder
|
||||||
|
#define xleft 2
|
||||||
|
#define xmiddle 7 /* between images and text, anyway; let's just use it for everything to be simpler */
|
||||||
|
#define xright 3
|
||||||
|
|
||||||
|
- (NSView *)tableView:(NSTableView *)tv viewForTableColumn:(NSTableColumn *)cc row:(NSInteger)row
|
||||||
|
{
|
||||||
|
NSView *v;
|
||||||
|
tableColumn *c = (tableColumn *) cc;
|
||||||
|
tablePart *part;
|
||||||
|
NSMutableArray *views;
|
||||||
|
NSView *view, *prev;
|
||||||
|
|
||||||
|
v = [[NSView alloc] initWithFrame:NSZeroRect];
|
||||||
|
|
||||||
|
views = [NSMutableArray new];
|
||||||
|
for (part in c.libui_col->parts)
|
||||||
|
[views addObject:[part mkView:self->libui_m row:row]];
|
||||||
|
if ([views count] == 0) // empty (TODO allow?)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
// arrange horizontally
|
||||||
|
prev = nil;
|
||||||
|
for (view in views) {
|
||||||
|
if (prev == nil) { // first view
|
||||||
|
[v addConstraint:mkConstraint(v, NSLayoutAttributeLeading,
|
||||||
|
NSLayoutRelationEqual,
|
||||||
|
view, NSLayoutAttributeLeading,
|
||||||
|
1, -xleft,
|
||||||
|
@"uiTableColumn first part horizontal constraint")];
|
||||||
|
prev = view;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
[v addConstraint:mkConstraint(prev, NSLayoutAttributeTrailing,
|
||||||
|
NSLayoutRelationEqual,
|
||||||
|
view, NSLayoutAttributeLeading,
|
||||||
|
1, -xmiddle,
|
||||||
|
@"uiTableColumn middle horizontal constraint")];
|
||||||
|
prev = view;
|
||||||
|
}
|
||||||
|
[v addConstraint:mkConstraint(prev, NSLayoutAttributeTrailing,
|
||||||
|
NSLayoutRelationEqual,
|
||||||
|
v, NSLayoutAttributeTrailing,
|
||||||
|
1, -xright,
|
||||||
|
@"uiTableColumn last part horizontal constraint")];
|
||||||
|
|
||||||
|
// and vertically
|
||||||
|
for (view in views)
|
||||||
|
[v addConstraint:mkConstraint(view, NSLayoutAttributeCenterY,
|
||||||
|
NSLayoutRelationEqual,
|
||||||
|
v, NSLayoutAttributeCenterY,
|
||||||
|
1, 0,
|
||||||
|
@"uiTableColumn part vertical constraint")];
|
||||||
|
|
||||||
|
done:
|
||||||
|
[views release];
|
||||||
|
// TODO autorelease?
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation tablePart
|
||||||
|
|
||||||
|
- (NSView *)mkView:(uiTableModel *)m row:(int)row;
|
||||||
|
{
|
||||||
|
void *data;
|
||||||
|
NSString *str;
|
||||||
|
NSView *view;
|
||||||
|
NSTextField *tf;
|
||||||
|
|
||||||
|
data = (*(m->mh->CellValue))(m->mh, m, row, self.mainColumn);
|
||||||
|
switch (self.type) {
|
||||||
|
case partText:
|
||||||
|
str = toNSString((char *) data);
|
||||||
|
uiFree(data);
|
||||||
|
tf = newLabel(str);
|
||||||
|
// TODO set wrap and ellipsize modes
|
||||||
|
view = tf;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if stretchy, don't hug, otherwise hug forcibly
|
||||||
|
if (self.expand)
|
||||||
|
[view setContentHuggingPriority:NSLayoutPriorityDefaultLow forOrientation:NSLayoutConstraintOrientationHorizontal];
|
||||||
|
else
|
||||||
|
[view setContentHuggingPriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationHorizontal];
|
||||||
|
// TODO autorelease?
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation tableColumn
|
||||||
|
@end
|
||||||
|
|
||||||
|
void *uiTableModelStrdup(const char *str)
|
||||||
|
{
|
||||||
|
// TODO don't we have this already?
|
||||||
|
char *dup;
|
||||||
|
|
||||||
|
dup = (char *) uiAlloc((strlen(str) + 1) * sizeof (char), "char[]");
|
||||||
|
strcpy(dup, str);
|
||||||
|
return dup;
|
||||||
|
}
|
||||||
|
|
||||||
|
uiTableModel *uiNewTableModel(uITableModelHandler *mh)
|
||||||
|
{
|
||||||
|
uiTableModel *m;
|
||||||
|
|
||||||
|
m = uiNew(uiTableModel);
|
||||||
|
m->mh = mh;
|
||||||
|
m->m = [[tableModel alloc] initWithModel:m];
|
||||||
|
m->tables = [NSMutableArray new];
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiFreeTableModel(uiTableModel *m)
|
||||||
|
{
|
||||||
|
if ([m->tables count] != 0)
|
||||||
|
userbug("You cannot free a uiTableModel while uiTables are using it.");
|
||||||
|
[m->tables release];
|
||||||
|
[m->m release];
|
||||||
|
uiFree(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiTableModelRowInserted(uiTableModel *m, int newIndex)
|
||||||
|
{
|
||||||
|
NSTableView *tv;
|
||||||
|
NSIndexSet *set;
|
||||||
|
|
||||||
|
set = [NSIndexSet indexSetWithIndex:index];
|
||||||
|
for (tv in m->tables)
|
||||||
|
[tv insertRowsAtIndexes:set withAnimation:NSTableViewAnimationEffectNone];
|
||||||
|
// set is autoreleased
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiTableModelRowChanged(uiTableModel *m, int index)
|
||||||
|
{
|
||||||
|
NSTableView *tv;
|
||||||
|
NSIndexSet *set, *cols;
|
||||||
|
|
||||||
|
set = [NSIndexSet indexSetWithIndex:index];
|
||||||
|
for (tv in m->tables) {
|
||||||
|
cols = [[NSIndexSet alloc] initWithIndexesInRange:NSMakeRange(0, [[tv tableColumns] count])];
|
||||||
|
[tv reloadDataForRowIndexes:set columnIndexes:cols];
|
||||||
|
[cols release];
|
||||||
|
}
|
||||||
|
// set is autoreleased
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiTableModelRowDeleted(uiTableModel *m, int oldIndex)
|
||||||
|
{
|
||||||
|
NSTableView *tv;
|
||||||
|
NSIndexSet *set;
|
||||||
|
|
||||||
|
set = [NSIndexSet indexSetWithIndex:index];
|
||||||
|
for (tv in m->tables)
|
||||||
|
[tv removeRowsAtIndexes:set withAnimation:NSTableViewAnimationEffectNone];
|
||||||
|
// set is autoreleased
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiTableColumnAppend(uiTableColumn *c, uiTableCellPart *part, int expand)
|
||||||
|
{
|
||||||
|
part->part.expand = expand;
|
||||||
|
[c->parts addObject:part->part];
|
||||||
|
}
|
||||||
|
|
||||||
|
_UI_EXTERN uiTableCellPart *uiNewTableTextPart(int modelColumn);
|
||||||
|
_UI_EXTERN void uiFreeTableCellPart(uiTableCellPart *p);
|
||||||
|
|
||||||
|
typedef struct uiTable uiTable;
|
||||||
|
#define uiTable(this) ((uiTable *) (this))
|
||||||
|
_UI_EXTERN uiTableColumn *uiTableAppendColumn(uiTable *t, const char *name);
|
||||||
|
_UI_EXTERN uiTableColumn *uiTableAppendTextColumn(uiTable *t, const char *name, int modelColumn);
|
||||||
|
_UI_EXTERN uiTable *uiNewTable(uiTableModel *model);
|
|
@ -3,22 +3,22 @@
|
||||||
|
|
||||||
static uiTableModelHandler mh;
|
static uiTableModelHandler mh;
|
||||||
|
|
||||||
static nt modelNumColumns(uiTableModel *m)
|
static nt modelNumColumns(uiTableModelHandler *mh, uiTableModel *m)
|
||||||
{
|
{
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uiTableModelColumnType modelColumnType(uiTableModel *m, int column)
|
static uiTableModelColumnType modelColumnType(uiTableModelHandler *mh, uiTableModel *m, int column)
|
||||||
{
|
{
|
||||||
return uiTableModelColumnString;
|
return uiTableModelColumnString;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int modelNumRows(uiTableModel *m)
|
static int modelNumRows(uiTableModelHandler *mh, uiTableModel *m)
|
||||||
{
|
{
|
||||||
return 15;
|
return 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *modelCellValue(uiTableModel *m, int row, int col)
|
static void *modelCellValue(uiTableModelHandler *mh, uiTableModel *m, int row, int col)
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ static void *modelCellValue(uiTableModel *m, int row, int col)
|
||||||
return uiTableModelStrdup(buf);
|
return uiTableModelStrdup(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void modelSetCellValue(uiTableModel *m, int row, int col, void *val)
|
static void modelSetCellValue(uiTableModelHandler *mh, uiTableModel *m, int row, int col, void *val)
|
||||||
{
|
{
|
||||||
// not implemented yet
|
// not implemented yet
|
||||||
}
|
}
|
||||||
|
|
11
uitable.h
11
uitable.h
|
@ -9,11 +9,11 @@ _UI_ENUM(uiTableModelColumnType) {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uiTableModelHandler {
|
struct uiTableModelHandler {
|
||||||
int (*NumColumns)(uiTableModel *);
|
int (*NumColumns)(uiTableModelHandler *, uiTableModel *);
|
||||||
uiTableModelColumnType (*ColumnType)(uiTableModel *, int);
|
uiTableModelColumnType (*ColumnType)(uiTableModelHandler *, uiTableModel *, int);
|
||||||
int (*NumRows)(uiTableModel *);
|
int (*NumRows)(uiTableModelHandler *, uiTableModel *);
|
||||||
void *(*CellValue)(uiTableModel *, int, int);
|
void *(*CellValue)(uiTableModelHandler *, uiTableModel *, int, int);
|
||||||
void (*SetCellValue)(uiTableModel *, int, int, void *);
|
void (*SetCellValue)(uiTableModelHandler *, uiTableModel *, int, int, void *);
|
||||||
};
|
};
|
||||||
|
|
||||||
_UI_EXTERN void *uiTableModelStrdup(const char *str);
|
_UI_EXTERN void *uiTableModelStrdup(const char *str);
|
||||||
|
@ -23,6 +23,7 @@ _UI_EXTERN void uiFreeTableModel(uiTableModel *m);
|
||||||
_UI_EXTERN void uiTableModelRowInserted(uiTableModel *m, int newIndex);
|
_UI_EXTERN void uiTableModelRowInserted(uiTableModel *m, int newIndex);
|
||||||
_UI_EXTERN void uiTableModelRowChanged(uiTableModel *m, int index);
|
_UI_EXTERN void uiTableModelRowChanged(uiTableModel *m, int index);
|
||||||
_UI_EXTERN void uiTableModelRowDeleted(uiTableModel *m, int oldIndex);
|
_UI_EXTERN void uiTableModelRowDeleted(uiTableModel *m, int oldIndex);
|
||||||
|
// TODO reordering/moving
|
||||||
|
|
||||||
typedef struct uiTableColumn uiTableColumn;
|
typedef struct uiTableColumn uiTableColumn;
|
||||||
typedef struct uiTableCellPart uiTableCellPart;
|
typedef struct uiTableCellPart uiTableCellPart;
|
||||||
|
|
Loading…
Reference in New Issue