summaryrefslogtreecommitdiff
path: root/new/parent_darwin.m
blob: abf0e5908b00a20a5ef43a89a869433539372659 (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
// 4 august 2014
#import "uipriv_darwin.h"

// calling -[className] on the content views of NSWindow, NSTabItem, and NSBox all return NSView, so I'm assuming I just need to override these
// fornunately:
// - NSWindow resizing calls -[setFrameSize:] (but not -[setFrame:])
// - NSTabView resizing calls both -[setFrame:] and -[setFrameSIze:] on the current tab
// - NSTabView switching tabs calls both -[setFrame:] and -[setFrameSize:] on the new tab
// so we just override setFrameSize:
// thanks to mikeash and JtRip in irc.freenode.net/#macdev
@interface uipParent : NSView {
// TODO
@public
	uiControl *child;
	intmax_t marginLeft;
	intmax_t marginTop;
	intmax_t marginRight;
	intmax_t marginBottom;
}
- (void)uiUpdateNow;
@end

@implementation uipParent

uiLogObjCClassAllocations

- (void)viewDidMoveToSuperview
{
	// we can't just use nil because NSTabView will set page views to nil when they're tabbed away
	// this means that we have to explicitly move them to the destroyed controls view when we're done with them, and likewise in NSWindow
	if ([self superview] == destroyedControlsView)
		if (self->child != NULL) {
			uiControlDestroy(self->child);
			self->child = NULL;
			[self release];
		}
	[super viewDidMoveToSuperview];
}

- (void)setFrameSize:(NSSize)s
{
	[super setFrameSize:s];
	[self uiUpdateNow];
}

// These are based on measurements from Interface Builder.
// These seem to be based on Auto Layout constants, but I don't see an API that exposes these...
// This one is 8 for most pairs of controls that I've tried; the only difference is between two pushbuttons, where it's 12...
#define macXPadding 8
// Likewise, this one appears to be 12 for pairs of push buttons...
#define macYPadding 8

- (void)uiUpdateNow
{
	uiSizing d;
	intmax_t x, y, width, height;

	if (self->child == NULL)
		return;
	x = [self bounds].origin.x + self->marginLeft;
	y = [self bounds].origin.y + self->marginTop;
	width = [self bounds].size.width - (self->marginLeft + self->marginRight);
	height = [self bounds].size.height - (self->marginTop + self->marginBottom);
	d.xPadding = macXPadding;
	d.yPadding = macYPadding;
	uiControlResize(self->child, x, y, width, height, &d);
}

@end

static uintptr_t parentHandle(uiParent *p)
{
	uipParent *pp = (uipParent *) (p->Internal);

	return (uintptr_t) pp;
}

static void parentSetChild(uiParent *p, uiControl *child)
{
	uipParent *pp = (uipParent *) (p->Internal);

	pp->child = child;
	if (pp->child != NULL)
		uiControlSetParent(child, p);
}

static void parentSetMargins(uiParent *p, intmax_t left, intmax_t top, intmax_t right, intmax_t bottom)
{
	uipParent *pp = (uipParent *) (p->Internal);

	pp->marginLeft = left;
	pp->marginTop = top;
	pp->marginRight = right;
	pp->marginBottom = bottom;
}

static void parentUpdate(uiParent *p)
{
	uipParent *pp = (uipParent *) (p->Internal);

	[pp uiUpdateNow];
}

uiParent *uiNewParent(uintptr_t osParent)
{
	uiParent *p;

	p = uiNew(uiParent);
	p->Internal = [[uipParent alloc] initWithFrame:NSZeroRect];
	p->Handle = parentHandle;
	p->SetChild = parentSetChild;
	p->SetMargins = parentSetMargins;
	p->Update = parentUpdate;
	// don't use osParent; we'll need to call specific selectors to set the parent view
	// and keep the view alive so we can release it properly later
	[((uipParent *) (p->Internal)) retain];
	return p;
}