mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-26 07:39:56 -06:00
another UI attempt, I guess.
sorry.
This commit is contained in:
292
src/libui_sdl/libui/darwin/tab.m
Normal file
292
src/libui_sdl/libui/darwin/tab.m
Normal file
@ -0,0 +1,292 @@
|
||||
// 15 august 2015
|
||||
#import "uipriv_darwin.h"
|
||||
|
||||
// TODO need to jiggle on tab change too (second page disabled tab label initially ambiguous)
|
||||
|
||||
@interface tabPage : NSObject {
|
||||
struct singleChildConstraints constraints;
|
||||
int margined;
|
||||
NSView *view; // the NSTabViewItem view itself
|
||||
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;
|
||||
};
|
||||
|
||||
@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;
|
||||
singleChildConstraintsEstablish(&(self->constraints),
|
||||
self->view, [self childView],
|
||||
uiDarwinControlHugsTrailingEdge(uiDarwinControl(self.c)),
|
||||
uiDarwinControlHugsBottom(uiDarwinControl(self.c)),
|
||||
self->margined,
|
||||
@"uiTab page");
|
||||
}
|
||||
|
||||
- (void)removeChildConstraints
|
||||
{
|
||||
singleChildConstraintsRemove(&(self->constraints), self->view);
|
||||
}
|
||||
|
||||
- (int)isMargined
|
||||
{
|
||||
return self->margined;
|
||||
}
|
||||
|
||||
- (void)setMargined:(int)m
|
||||
{
|
||||
self->margined = m;
|
||||
singleChildConstraintsSetMargined(&(self->constraints), self->margined);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static void uiTabDestroy(uiControl *c)
|
||||
{
|
||||
uiTab *t = uiTab(c);
|
||||
tabPage *page;
|
||||
|
||||
// first remove all tab pages so we can destroy all the children
|
||||
while ([t->tabview numberOfTabViewItems] != 0)
|
||||
[t->tabview removeTabViewItem:[t->tabview tabViewItemAtIndex:0]];
|
||||
// then destroy all the children
|
||||
for (page in t->pages) {
|
||||
[page removeChildConstraints];
|
||||
uiControlSetParent(page.c, NULL);
|
||||
uiDarwinControlSetSuperview(uiDarwinControl(page.c), nil);
|
||||
uiControlDestroy(page.c);
|
||||
}
|
||||
// and finally destroy ourselves
|
||||
[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];
|
||||
// and this gets rid of some weird issues with regards to box alignment
|
||||
jiggleViewLayout(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];
|
||||
// note: if we turn off the autoresizing mask, nothing shows up
|
||||
uiDarwinControlSetSuperview(uiDarwinControl(child), view);
|
||||
uiDarwinControlSyncEnableState(uiDarwinControl(child), uiControlEnabledToUser(uiControl(t)));
|
||||
|
||||
// the documentation says these can be nil but the headers say these must not be; let's be safe and make them non-nil anyway
|
||||
pageID = [NSObject new];
|
||||
page = [[[tabPage alloc] initWithView:view pageID:pageID] autorelease];
|
||||
page.c = child;
|
||||
|
||||
// don't hug, just in case we're a stretchy tab
|
||||
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:toNSString(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];
|
||||
}
|
||||
|
||||
uiTab *uiNewTab(void)
|
||||
{
|
||||
uiTab *t;
|
||||
|
||||
uiDarwinNewControl(uiTab, t);
|
||||
|
||||
t->tabview = [[NSTabView alloc] initWithFrame:NSZeroRect];
|
||||
// also good for NSTabView (same selector and everything)
|
||||
uiDarwinSetControlFont((NSControl *) (t->tabview), NSRegularControlSize);
|
||||
|
||||
t->pages = [NSMutableArray new];
|
||||
|
||||
// default to low hugging to not hug edges
|
||||
t->horzHuggingPri = NSLayoutPriorityDefaultLow;
|
||||
t->vertHuggingPri = NSLayoutPriorityDefaultLow;
|
||||
|
||||
return t;
|
||||
}
|
Reference in New Issue
Block a user