summaryrefslogtreecommitdiff
path: root/prev/table_darwin.m
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2015-12-11 20:37:59 -0500
committerPietro Gagliardi <[email protected]>2015-12-11 20:37:59 -0500
commitf8e3f12ab02b528f2a05a4f713d7af7ea8e44b42 (patch)
tree82dedf4d37f0f6d31e88ebb2ca1ce6499dead261 /prev/table_darwin.m
parente34c561ed5bedeb180437ec165882b98d70d38c1 (diff)
LET'S GET THIS FINAL REWRITE EVER STARTED
Diffstat (limited to 'prev/table_darwin.m')
-rw-r--r--prev/table_darwin.m195
1 files changed, 195 insertions, 0 deletions
diff --git a/prev/table_darwin.m b/prev/table_darwin.m
new file mode 100644
index 0000000..f04aae8
--- /dev/null
+++ b/prev/table_darwin.m
@@ -0,0 +1,195 @@
+// 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, NSTableViewDelegate> {
+@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
+{
+ void *ret;
+ NSString *s;
+ intptr_t colnum;
+ char *str;
+ int type = colTypeText;
+
+ colnum = ((goTableColumn *) col)->gocolnum;
+ ret = goTableDataSource_getValue(self->gotable, (intptr_t) row, colnum, &type);
+ switch (type) {
+ case colTypeImage:
+ // TODO free the returned image when done somehow
+ return (id) ret;
+ case colTypeCheckbox:
+ if (ret == NULL)
+ return nil;
+ return (id) [NSNumber numberWithInt:1];
+ }
+ str = (char *) ret;
+ s = [NSString stringWithUTF8String:str];
+ free(str); // allocated with C.CString() on the Go side
+ return (id) s;
+}
+
+- (void)tableView:(NSTableView *)view setObjectValue:(id)value forTableColumn:(NSTableColumn *)col row:(NSInteger)row
+{
+ intptr_t colnum;
+ NSNumber *number = (NSNumber *) value; // thanks to mikeash in irc.freenode.net/#macdev
+
+ colnum = ((goTableColumn *) col)->gocolnum;
+ goTableDataSource_toggled(self->gotable, (intptr_t) row, colnum, [number boolValue]);
+}
+
+- (void)tableViewSelectionDidChange:(NSNotification *)note
+{
+ tableSelectionChanged(self->gotable);
+}
+
+@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, int type, BOOL editable)
+{
+ goTableColumn *c;
+ NSImageCell *ic;
+ NSButtonCell *bc;
+ NSLineBreakMode lbm = NSLineBreakByTruncatingTail; // default for most types
+
+ c = [[goTableColumn alloc] initWithIdentifier:nil];
+ c->gocolnum = colnum;
+ switch (type) {
+ case colTypeImage:
+ ic = [[NSImageCell alloc] initImageCell:nil];
+ // this is the behavior we want, which differs from the Interface Builder default of proportionally down
+ [ic setImageScaling:NSImageScaleProportionallyUpOrDown];
+ // these two, however, ARE Interface Builder defaults
+ [ic setImageFrameStyle:NSImageFrameNone];
+ [ic setImageAlignment:NSImageAlignCenter];
+ [c setDataCell:ic];
+ break;
+ case colTypeCheckbox:
+ bc = [[NSButtonCell alloc] init];
+ [bc setBezelStyle:NSRegularSquareBezelStyle]; // not explicitly stated as such in Interface Builder; extracted with a test program
+ [bc setButtonType:NSSwitchButton];
+ [bc setBordered:NO];
+ [bc setTransparent:NO];
+ [bc setAllowsMixedState:NO];
+ [bc setTitle:@""]; // no label
+ lbm = NSLineBreakByWordWrapping; // Interface Builder sets this mode for this type
+ [c setDataCell:bc];
+ break;
+ }
+ // otherwise just use the current cell
+ [c setEditable:editable];
+ [[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:lbm];
+ [[c dataCell] setUsesSingleLineMode:NO];
+ [[c dataCell] setTruncatesLastVisibleLine:NO];
+ [toNSTableView(t) addTableColumn:c];
+}
+
+void tableUpdate(id t)
+{
+ [toNSTableView(t) reloadData];
+}
+
+// also sets the delegate
+void tableMakeDataSource(id table, void *gotable)
+{
+ goTableDataSource *model;
+
+ model = [goTableDataSource new];
+ model->gotable = gotable;
+ [toNSTableView(table) setDataSource:model];
+ [toNSTableView(table) setDelegate: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;
+}
+
+intptr_t tableSelected(id table)
+{
+ return (intptr_t) [toNSTableView(table) selectedRow];
+}
+
+void tableSelect(id table, intptr_t row)
+{
+ [toNSTableView(table) deselectAll:table];
+ if (row != -1)
+ [toNSTableView(table) selectRowIndexes:[NSIndexSet indexSetWithIndex:((NSUInteger) row)] byExtendingSelection:NO];
+}