diff --git a/objc_darwin.h b/objc_darwin.h index 03dafdf..f9f0822 100644 --- a/objc_darwin.h +++ b/objc_darwin.h @@ -33,6 +33,12 @@ struct xpoint { intptr_t y; }; +struct xprefsize { + intptr_t width; + intptr_t height; + intptr_t yoff; +}; + /* objc_darwin.m */ extern id toNSString(char *); extern char *fromNSString(id); @@ -86,10 +92,11 @@ extern uintptr_t listboxIndexesNext(id, uintptr_t); extern intptr_t listboxLen(id); /* prefsize_darwin.m */ -extern struct xsize controlPrefSize(id); -extern struct xsize listboxPrefSize(id); -extern struct xsize pbarPrefSize(id); -extern struct xsize areaPrefSize(id); +extern struct xprefsize controlPrefSize(id, BOOL); +extern struct xprefsize labelPrefSize(id, BOOL); +extern struct xprefsize listboxPrefSize(id, BOOL); +extern struct xprefsize pbarPrefSize(id, BOOL); +extern struct xprefsize areaPrefSize(id, BOOL); /* sysdata_darwin.m */ extern void addControl(id, id); diff --git a/prefsize_darwin.go b/prefsize_darwin.go index 629a748..4e10a6a 100644 --- a/prefsize_darwin.go +++ b/prefsize_darwin.go @@ -10,40 +10,46 @@ Cocoa doesn't provide a reliable way to get the preferred size of a control (you */ // standard case: control immediately passed in -func controlPrefSize(control C.id) (width int, height int) { - r := C.controlPrefSize(control) - return int(r.width), int(r.height) +func controlPrefSize(control C.id, alternate C.BOOL) (width int, height int, yoff int) { + r := C.controlPrefSize(control, alternate) + return int(r.width), int(r.height), int(r.yoff) +} + +// Labels have special yoff calculation +func labelPrefSize(control C.id, alternate C.BOOL) (width int, height int, yoff int) { + r := C.labelPrefSize(control, alternate) + return int(r.width), int(r.height), int(r.yoff) } // NSTableView is actually in a NSScrollView so we have to get it out first -func listboxPrefSize(control C.id) (width int, height int) { - r := C.listboxPrefSize(control) - return int(r.width), int(r.height) +func listboxPrefSize(control C.id, alternate C.BOOL) (width int, height int, yoff int) { + r := C.listboxPrefSize(control, alternate) + return int(r.width), int(r.height), int(r.yoff) } // and for type checking reasons, progress bars are separate despite responding to -[sizeToFit] -func pbarPrefSize(control C.id) (width int, height int) { - r := C.pbarPrefSize(control) - return int(r.width), int(r.height) +func pbarPrefSize(control C.id, alternate C.BOOL) (width int, height int, yoff int) { + r := C.pbarPrefSize(control, alternate) + return int(r.width), int(r.height), int(r.yoff) } // Areas know their own preferred size -func areaPrefSize(control C.id) (width int, height int) { - r := C.areaPrefSize(control) - return int(r.width), int(r.height) +func areaPrefSize(control C.id, alternate C.BOOL) (width int, height int, yoff int) { + r := C.areaPrefSize(control, alternate) + return int(r.width), int(r.height), int(r.yoff) } -var prefsizefuncs = [nctypes]func(C.id) (int, int){ +var prefsizefuncs = [nctypes]func(C.id, C.BOOL) (int, int, int){ c_button: controlPrefSize, c_checkbox: controlPrefSize, c_combobox: controlPrefSize, c_lineedit: controlPrefSize, - c_label: controlPrefSize, + c_label: labelPrefSize, c_listbox: listboxPrefSize, c_progressbar: pbarPrefSize, c_area: areaPrefSize, } -func (s *sysData) preferredSize() (width int, height int) { - return prefsizefuncs[s.ctype](s.id) +func (s *sysData) preferredSize() (width int, height int, yoff int) { + return prefsizefuncs[s.ctype](s.id, toBOOL(s.alternate)) } diff --git a/prefsize_darwin.m b/prefsize_darwin.m index 1d97d01..932038b 100644 --- a/prefsize_darwin.m +++ b/prefsize_darwin.m @@ -2,12 +2,15 @@ #include "objc_darwin.h" #import +#import +#import #import #import #import #define to(T, x) ((T *) (x)) #define toNSControl(x) to(NSControl, (x)) +#define toNSTextField(x) to(NSTextField, (x)) #define toNSScrollView(x) to(NSScrollView, (x)) #define toNSTableView(x) to(NSTableView, (x)) #define toNSProgressIndicator(x) to(NSProgressIndicator, (x)) @@ -16,58 +19,87 @@ #define listboxInScrollView(x) toNSTableView(inScrollView((x))) #define areaInScrollView(x) inScrollView((x)) -struct xsize controlPrefSize(id control) +struct xprefsize controlPrefSize(id control, BOOL alternate) { NSControl *c; NSRect r; - struct xsize s; + struct xprefsize s; c = toNSControl(control); [c sizeToFit]; r = [c frame]; s.width = (intptr_t) r.size.width; s.height = (intptr_t) r.size.height; + s.yoff = 0; // no yoff for most controls return s; } -struct xsize listboxPrefSize(id scrollview) +struct xprefsize labelPrefSize(id control, BOOL alternate) +{ + NSControl *c; + NSRect r; + struct xprefsize s; + + c = toNSControl(control); + [c sizeToFit]; + r = [c frame]; + s.width = (intptr_t) r.size.width; + s.height = (intptr_t) r.size.height; + s.yoff = 0; // no yoff for standalone labels + if (!alternate) { + // TODO this seems really hacky + // temporarily enable the border, compute its height, and take the height difference + [toNSTextField(c) setBordered:YES]; + [c sizeToFit]; + r = [c frame]; + [toNSTextField(c) setBordered:NO]; + // - 1 since the sizes are exclusive (????? TODO) + s.yoff = ((intptr_t) r.size.height) - s.height - 1; + } + return s; +} + +struct xprefsize listboxPrefSize(id scrollview, BOOL altenrate) { NSTableView *c; NSRect r; - struct xsize s; + struct xprefsize s; c = listboxInScrollView(toNSScrollView(scrollview)); [c sizeToFit]; r = [c frame]; s.width = (intptr_t) r.size.width; s.height = (intptr_t) r.size.height; + s.yoff = 0; // no yoff for listboxes return s; } -struct xsize pbarPrefSize(id control) +struct xprefsize pbarPrefSize(id control, BOOL alternate) { NSProgressIndicator *c; NSRect r; - struct xsize s; + struct xprefsize s; c = toNSProgressIndicator(control); [c sizeToFit]; r = [c frame]; s.width = (intptr_t) r.size.width; s.height = (intptr_t) r.size.height; + s.yoff = 0; // no yoff for progress bars return s; } -struct xsize areaPrefSize(id scrollview) +struct xprefsize areaPrefSize(id scrollview, BOOL alternate) { NSView *c; NSRect r; - struct xsize s; + struct xprefsize s; c = areaInScrollView(toNSScrollView(scrollview)); // don't size to fit; the frame size is already the size we want r = [c frame]; s.width = (intptr_t) r.size.width; s.height = (intptr_t) r.size.height; + s.yoff = 0; // no yoff for areas return s; -} \ No newline at end of file +}