#import "uipriv_darwin.h"
@interface tabPage : NSObject {
uiprivSingleChildConstraints constraints;
int margined;
NSView *view; NSObject *pageID;
}
@property uiControl *c;
@property NSLayoutPriority oldHorzHuggingPri;
@property NSLayoutPriority oldVertHuggingPri;
- (id)initWithView:(NSView *)v pageID:(NSObject *)o;
- (NSView *)childView;
- (void)establishChildConstraints;
- (void)removeChildConstraints;
- (int)isMargined;
- (void)setMargined:(int)m;
@end
struct uiTab {
uiDarwinControl c;
NSTabView *tabview;
NSMutableArray *pages;
NSLayoutPriority horzHuggingPri;
NSLayoutPriority vertHuggingPri;
void (*onSelected)(uiTab *, void *);
void *onSelectedData;
};
@implementation tabPage
- (id)initWithView:(NSView *)v pageID:(NSObject *)o
{
self = [super init];
if (self != nil) {
self->view = [v retain];
self->pageID = [o retain];
}
return self;
}
- (void)dealloc
{
[self removeChildConstraints];
[self->view release];
[self->pageID release];
[super dealloc];
}
- (NSView *)childView
{
return (NSView *) uiControlHandle(self.c);
}
- (void)establishChildConstraints
{
[self removeChildConstraints];
if (self.c == NULL)
return;
uiprivSingleChildConstraintsEstablish(&(self->constraints),
self->view, [self childView],
uiDarwinControlHugsTrailingEdge(uiDarwinControl(self.c)),
uiDarwinControlHugsBottom(uiDarwinControl(self.c)),
self->margined,
@"uiTab page");
}
- (void)removeChildConstraints
{
uiprivSingleChildConstraintsRemove(&(self->constraints), self->view);
}
- (int)isMargined
{
return self->margined;
}
- (void)setMargined:(int)m
{
self->margined = m;
uiprivSingleChildConstraintsSetMargined(&(self->constraints), self->margined);
}
@end
@interface uiprivTabDelegate: NSObject<NSTabViewDelegate> {
uiTab *tab;
}
- (id)initWithTab:(uiTab *)t;
- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem;
@end
@implementation uiprivTabDelegate
- (id)initWithTab:(uiTab *)t
{
self = [super init];
if (self)
self->tab = t;
return self;
}
- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem
{
uiTab *t = self->tab;
(*(t->onSelected))(t, t->onSelectedData);
}
@end
static void defaultOnSelected(uiTab *t, void*data)
{
}
static void uiTabDestroy(uiControl *c)
{
uiTab *t = uiTab(c);
tabPage *page;
uiprivTabDelegate *delegate;
uiTabOnSelected(t, defaultOnSelected, NULL);
while ([t->tabview numberOfTabViewItems] != 0)
[t->tabview removeTabViewItem:[t->tabview tabViewItemAtIndex:0]];
for (page in t->pages) {
[page removeChildConstraints];
uiControlSetParent(page.c, NULL);
uiDarwinControlSetSuperview(uiDarwinControl(page.c), nil);
uiControlDestroy(page.c);
}
delegate = [t->tabview delegate];
[t->tabview setDelegate:nil];
[delegate release];
[t->pages release];
[t->tabview release];
uiFreeControl(uiControl(t));
}
uiDarwinControlDefaultHandle(uiTab, tabview)
uiDarwinControlDefaultParent(uiTab, tabview)
uiDarwinControlDefaultSetParent(uiTab, tabview)
uiDarwinControlDefaultToplevel(uiTab, tabview)
uiDarwinControlDefaultVisible(uiTab, tabview)
uiDarwinControlDefaultShow(uiTab, tabview)
uiDarwinControlDefaultHide(uiTab, tabview)
uiDarwinControlDefaultEnabled(uiTab, tabview)
uiDarwinControlDefaultEnable(uiTab, tabview)
uiDarwinControlDefaultDisable(uiTab, tabview)
static void uiTabSyncEnableState(uiDarwinControl *c, int enabled)
{
uiTab *t = uiTab(c);
tabPage *page;
if (uiDarwinShouldStopSyncEnableState(uiDarwinControl(t), enabled))
return;
for (page in t->pages)
uiDarwinControlSyncEnableState(uiDarwinControl(page.c), enabled);
}
uiDarwinControlDefaultSetSuperview(uiTab, tabview)
static void tabRelayout(uiTab *t)
{
tabPage *page;
for (page in t->pages)
[page establishChildConstraints];
uiprivJiggleViewLayout(t->tabview);
}
BOOL uiTabHugsTrailingEdge(uiDarwinControl *c)
{
uiTab *t = uiTab(c);
return t->horzHuggingPri < NSLayoutPriorityWindowSizeStayPut;
}
BOOL uiTabHugsBottom(uiDarwinControl *c)
{
uiTab *t = uiTab(c);
return t->vertHuggingPri < NSLayoutPriorityWindowSizeStayPut;
}
static void uiTabChildEdgeHuggingChanged(uiDarwinControl *c)
{
uiTab *t = uiTab(c);
tabRelayout(t);
}
static NSLayoutPriority uiTabHuggingPriority(uiDarwinControl *c, NSLayoutConstraintOrientation orientation)
{
uiTab *t = uiTab(c);
if (orientation == NSLayoutConstraintOrientationHorizontal)
return t->horzHuggingPri;
return t->vertHuggingPri;
}
static void uiTabSetHuggingPriority(uiDarwinControl *c, NSLayoutPriority priority, NSLayoutConstraintOrientation orientation)
{
uiTab *t = uiTab(c);
if (orientation == NSLayoutConstraintOrientationHorizontal)
t->horzHuggingPri = priority;
else
t->vertHuggingPri = priority;
uiDarwinNotifyEdgeHuggingChanged(uiDarwinControl(t));
}
static void uiTabChildVisibilityChanged(uiDarwinControl *c)
{
uiTab *t = uiTab(c);
tabRelayout(t);
}
void uiTabAppend(uiTab *t, const char *name, uiControl *child)
{
uiTabInsertAt(t, name, [t->pages count], child);
}
void uiTabInsertAt(uiTab *t, const char *name, int n, uiControl *child)
{
tabPage *page;
NSView *view;
NSTabViewItem *i;
NSObject *pageID;
uiControlSetParent(child, uiControl(t));
view = [[[NSView alloc] initWithFrame:NSZeroRect] autorelease];
uiDarwinControlSetSuperview(uiDarwinControl(child), view);
uiDarwinControlSyncEnableState(uiDarwinControl(child), uiControlEnabledToUser(uiControl(t)));
pageID = [NSObject new];
page = [[[tabPage alloc] initWithView:view pageID:pageID] autorelease];
page.c = child;
page.oldHorzHuggingPri = uiDarwinControlHuggingPriority(uiDarwinControl(page.c), NSLayoutConstraintOrientationHorizontal);
page.oldVertHuggingPri = uiDarwinControlHuggingPriority(uiDarwinControl(page.c), NSLayoutConstraintOrientationVertical);
uiDarwinControlSetHuggingPriority(uiDarwinControl(page.c), NSLayoutPriorityDefaultLow, NSLayoutConstraintOrientationHorizontal);
uiDarwinControlSetHuggingPriority(uiDarwinControl(page.c), NSLayoutPriorityDefaultLow, NSLayoutConstraintOrientationVertical);
[t->pages insertObject:page atIndex:n];
i = [[[NSTabViewItem alloc] initWithIdentifier:pageID] autorelease];
[i setLabel:uiprivToNSString(name)];
[i setView:view];
[t->tabview insertTabViewItem:i atIndex:n];
tabRelayout(t);
}
void uiTabDelete(uiTab *t, int n)
{
tabPage *page;
uiControl *child;
NSTabViewItem *i;
page = (tabPage *) [t->pages objectAtIndex:n];
uiDarwinControlSetHuggingPriority(uiDarwinControl(page.c), page.oldHorzHuggingPri, NSLayoutConstraintOrientationHorizontal);
uiDarwinControlSetHuggingPriority(uiDarwinControl(page.c), page.oldVertHuggingPri, NSLayoutConstraintOrientationVertical);
child = page.c;
[page removeChildConstraints];
[t->pages removeObjectAtIndex:n];
uiControlSetParent(child, NULL);
uiDarwinControlSetSuperview(uiDarwinControl(child), nil);
i = [t->tabview tabViewItemAtIndex:n];
[t->tabview removeTabViewItem:i];
tabRelayout(t);
}
int uiTabNumPages(uiTab *t)
{
return [t->pages count];
}
int uiTabMargined(uiTab *t, int n)
{
tabPage *page;
page = (tabPage *) [t->pages objectAtIndex:n];
return [page isMargined];
}
void uiTabSetMargined(uiTab *t, int n, int margined)
{
tabPage *page;
page = (tabPage *) [t->pages objectAtIndex:n];
[page setMargined:margined];
}
int uiTabSelected(uiTab *t)
{
NSTabViewItem *selectedTabViewItem = [t->tabview selectedTabViewItem];
return [t->tabview indexOfTabViewItem:selectedTabViewItem];
}
void uiTabSetSelected(uiTab *t, int index)
{
if (index < 0 || index >= uiTabNumPages(t))
return;
[t->tabview selectTabViewItemAtIndex:index];
}
void uiTabOnSelected(uiTab *t, void (*f)(uiTab *, void *), void *data)
{
t->onSelected = f;
t->onSelectedData = data;
}
uiTab *uiNewTab(void)
{
uiTab *t;
uiprivTabDelegate *delegate;
uiDarwinNewControl(uiTab, t);
t->tabview = [[NSTabView alloc] initWithFrame:NSZeroRect];
delegate = [[uiprivTabDelegate alloc] initWithTab:t];
[t->tabview setDelegate:delegate];
uiDarwinSetControlFont((NSControl *) (t->tabview), NSRegularControlSize);
t->pages = [NSMutableArray new];
t->horzHuggingPri = NSLayoutPriorityDefaultLow;
t->vertHuggingPri = NSLayoutPriorityDefaultLow;
uiTabOnSelected(t, defaultOnSelected, NULL);
return t;
}