summaryrefslogtreecommitdiff
path: root/redo/table_darwin.m
blob: 70d92603dc13bddbfb3d7422e2360c9900affa39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// 29 july 2014

#import "objc_darwin.h"
#import "_cgo_export.h"
#import <Cocoa/Cocoa.h>

#define toNSTableView(x) ((NSTableView *) (x))

// NSTableColumn provides no provision to store an integer data
// it does provide an identifier tag, but that's a NSString, and I'd rather not risk the conversion overhead
@interface goTableColumn : NSTableColumn {
@public
	intptr_t gocolnum;
}
@end

@implementation goTableColumn
@end

@interface goTableDataSource : NSObject <NSTableViewDataSource> {
@public
	void *gotable;
}
@end

@implementation goTableDataSource

- (NSInteger)numberOfRowsInTableView:(NSTableView *)view
{
	return (NSInteger) goTableDataSource_getRowCount(self->gotable);
}

- (id)tableView:(NSTableView *)view objectValueForTableColumn:(NSTableColumn *)col row:(NSInteger)row
{
	char *str;
	NSString *s;
	intptr_t colnum;

	colnum = ((goTableColumn *) col)->gocolnum;
	str = goTableDataSource_getValue(self->gotable, (intptr_t) row, colnum);
	s = [NSString stringWithUTF8String:str];
	free(str);		// allocated with C.CString() on the Go side
	return s;
}

@end

id newTable(void)
{
	NSTableView *t;

	t = [[NSTableView alloc] initWithFrame:NSZeroRect];
	[t setAllowsColumnReordering:NO];
	[t setAllowsColumnResizing:YES];
	[t setAllowsMultipleSelection:NO];
	[t setAllowsEmptySelection:YES];
	[t setAllowsColumnSelection:NO];
	return (id) t;
}

void tableAppendColumn(id t, intptr_t colnum, char *name)
{
	goTableColumn *c;

	c = [[goTableColumn alloc] initWithIdentifier:nil];
	c->gocolnum = colnum;
	[c setEditable:NO];
	[[c headerCell] setStringValue:[NSString stringWithUTF8String:name]];
	setSmallControlFont((id) [c headerCell]);
	setStandardControlFont((id) [c dataCell]);
	// the following are according to Interface Builder
	// for the header cell, a stub program had to be written because Interface Builder doesn't support editing header cells directly
	[[c headerCell] setScrollable:NO];
	[[c headerCell] setWraps:NO];
	[[c headerCell] setLineBreakMode:NSLineBreakByTruncatingTail];
	[[c headerCell] setUsesSingleLineMode:NO];
	[[c headerCell] setTruncatesLastVisibleLine:NO];
	[[c dataCell] setScrollable:NO];
	[[c dataCell] setWraps:NO];
	[[c dataCell] setLineBreakMode:NSLineBreakByTruncatingTail];
	[[c dataCell] setUsesSingleLineMode:NO];
	[[c dataCell] setTruncatesLastVisibleLine:NO];
	[toNSTableView(t) addTableColumn:c];
}

void tableUpdate(id t)
{
	[toNSTableView(t) reloadData];
}

void tableMakeDataSource(id table, void *gotable)
{
	goTableDataSource *model;

	model = [goTableDataSource new];
	model->gotable = gotable;
	[toNSTableView(table) setDataSource:model];
}

// -[NSTableView sizeToFit] does not actually size to fit
// -[NSTableColumn sizeToFit] is just for the header
// -[NSTableColumn sizeToFit] can work for guessing but overrides user settings
// -[[NSTableColumn headerCell] cellSize] does NOT (despite being documented as returning the minimum needed size)
// Let's write our own to prefer:
// - width of the sum of all columns's current widths
// - height of 5 rows (arbitrary count; seems reasonable) + header view height
// Hopefully this is reasonable.
struct xsize tablePreferredSize(id control)
{
	NSTableView *t;
	NSArray *columns;
	struct xsize s;
	NSUInteger i, n;
	NSTableColumn *c;

	t = toNSTableView(control);
	columns = [t tableColumns];
	n = [columns count];
	s.width = 0;
	for (i = 0; i < n; i++) {
		CGFloat width;

		c = (NSTableColumn *) [columns objectAtIndex:i];
		s.width += (intptr_t) [c width];
	}
	s.height = 5 * (intptr_t) [t rowHeight];
	s.height += (intptr_t) [[t headerView] frame].size.height;
	return s;
}