Fixed label alignment on Mac OS X for real now.

This commit is contained in:
Pietro Gagliardi 2014-06-26 10:06:58 -04:00
parent dd305141fd
commit 67f1bcfc3c
4 changed files with 57 additions and 9 deletions

View File

@ -12,7 +12,7 @@ type sysSizeData struct {
// nothing for mac
// for the actual resizing
// neighbor control alignment rect/baseline info
neighborAlign C.struct_xalignment
}
// THIS IS A GUESS. TODO.
@ -50,14 +50,34 @@ func (s *sysData) translateAllocationCoords(allocations []*allocation, winwidth,
func (s *sysData) commitResize(c *allocation, d *sysSizeData) {
if s.ctype == c_label && !s.alternate && c.neighbor != nil {
c.neighbor.getAuxResizeInfo(d)
// get this control's alignment rect and baseline
// align
if d.neighborAlign.baseline != 0 { // no adjustment needed if the given control has no baseline
// in order for the baseline value to be correct, the label MUST BE AT THE HEIGHT THAT OS X WANTS IT TO BE!
// otherwise, the baseline calculation will be relative to the bottom of the control, and everything will be wrong
origsize := C.controlPrefSize(s.id)
c.height = int(origsize.height)
newrect := C.struct_xrect{
x: C.intptr_t(c.x),
y: C.intptr_t(c.y),
width: C.intptr_t(c.width),
height: C.intptr_t(c.height),
}
ourAlign := C.alignmentInfo(s.id, newrect)
// we need to find the exact Y positions of the baselines
// fortunately, this is easy now that (x,y) is the bottom-left corner
thisbasey := ourAlign.alignmentRect.y + ourAlign.baseline
neighborbasey := d.neighborAlign.alignmentRect.y + d.neighborAlign.baseline
// now the amount we have to move the label down by is easy to find
yoff := neighborbasey - thisbasey
// and we just add that
c.y += int(yoff)
}
// TODO if there's no baseline, the alignment should be to the top /of the alignment rect/, not the frame
}
C.setRect(s.id, C.intptr_t(c.x), C.intptr_t(c.y), C.intptr_t(c.width), C.intptr_t(c.height))
}
func (s *sysData) getAuxResizeInfo(d *sysSizeData) {
// get this control's alignment rect and baseline
d.neighborAlign = C.alignmentInfo(s.id, C.frame(s.id))
}
/*

View File

@ -15,7 +15,7 @@
#include <stdint.h>
/* wrapper types since the meaning of NSRect, NSSize, and NSPoint are CPU architectured-dependent; also because they're in an Objective-C-only header */
/* wrapper types since the meaning of NSRect, NSSize, and NSPoint are CPU architecture3d-dependent; also because they're in an Objective-C-only header */
struct xrect {
intptr_t x;
intptr_t y;
@ -33,6 +33,11 @@ struct xpoint {
intptr_t y;
};
struct xalignment {
struct xrect alignmentRect;
intptr_t baseline;
};
/* objc_darwin.m */
extern id toNSString(char *);
extern char *fromNSString(id);
@ -90,6 +95,7 @@ extern struct xsize controlPrefSize(id);
extern struct xsize listboxPrefSize(id);
extern struct xsize pbarPrefSize(id);
extern struct xsize areaPrefSize(id);
extern struct xalignment alignmentInfo(id, struct xrect);
/* sysdata_darwin.m */
extern void addControl(id, id);

View File

@ -2,16 +2,19 @@
#include "objc_darwin.h"
#import <AppKit/NSControl.h>
#import <AppKit/NSView.h>
#import <AppKit/NSScrollView.h>
#import <AppKit/NSTableView.h>
#import <AppKit/NSProgressIndicator.h>
#import <AppKit/NSView.h>
// needed for the methods called by alignmentInfo()
#import <AppKit/NSLayoutConstraint.h>
#define to(T, x) ((T *) (x))
#define toNSControl(x) to(NSControl, (x))
#define toNSScrollView(x) to(NSScrollView, (x))
#define toNSTableView(x) to(NSTableView, (x))
#define toNSProgressIndicator(x) to(NSProgressIndicator, (x))
#define toNSView(x) to(NSView, (x))
#define inScrollView(x) ([toNSScrollView((x)) documentView])
#define listboxInScrollView(x) toNSTableView(inScrollView((x)))
@ -72,3 +75,23 @@ struct xsize areaPrefSize(id scrollview)
s.height = (intptr_t) r.size.height;
return s;
}
struct xalignment alignmentInfo(id c, struct xrect newrect)
{
NSView *v;
struct xalignment a;
NSRect r;
v = toNSView(c);
r = NSMakeRect((CGFloat) newrect.x,
(CGFloat) newrect.y,
(CGFloat) newrect.width,
(CGFloat) newrect.height);
r = [v alignmentRectForFrame:r];
a.alignmentRect.x = (intptr_t) r.origin.x;
a.alignmentRect.y = (intptr_t) r.origin.y;
a.alignmentRect.width = (intptr_t) r.size.width;
a.alignmentRect.height = (intptr_t) r.size.height;
a.baseline = (intptr_t) [v baselineOffsetFromBottom];
return a;
}

View File

@ -1,7 +1,6 @@
ALL:
- vertical alignment of labels is a botch right now
- os x: very very wrong
- grids: currently requires labels to be filling for this to work
- vertical alignment of labels still has some flaws
- gtk+: currently requires labels to be filling for this to work: grids don't do this by default, for instance
- won't cause any issues, just an inconvenience that should be addressed
MAC OS X: