Removed the old OS X code.
This commit is contained in:
parent
fec3129664
commit
269e99aec3
33
darwin/bin.m
33
darwin/bin.m
|
@ -1,33 +0,0 @@
|
|||
// 28 april 2015
|
||||
#import "uipriv_darwin.h"
|
||||
|
||||
int binHasOSParent(uiBin *b)
|
||||
{
|
||||
NSView *v;
|
||||
|
||||
// note that:
|
||||
// - the superview of a NSWindow content view is the window frame
|
||||
// - the superview of *the active NSTabView page* is the NSTabView itself (we don't have to worry about other pages because if there are pages, then at least one page will be active, so we will eventually get here)
|
||||
v = (NSView *) uiControlHandle(uiControl(b));
|
||||
return [v superview] != nil;
|
||||
}
|
||||
|
||||
void binSetOSParent(uiBin *b, uintptr_t osParent)
|
||||
{
|
||||
complain("TODO");
|
||||
}
|
||||
|
||||
void binRemoveOSParent(uiBin *b)
|
||||
{
|
||||
complain("TODO");
|
||||
}
|
||||
|
||||
void binResizeRootAndUpdate(uiBin *b, intmax_t x, intmax_t y, intmax_t width, intmax_t height)
|
||||
{
|
||||
// not used on OS X
|
||||
}
|
||||
|
||||
void binTranslateMargins(uiBin *b, intmax_t *left, intmax_t *top, intmax_t *right, intmax_t *bottom, uiSizing *d)
|
||||
{
|
||||
// not used on OS X
|
||||
}
|
|
@ -1,186 +0,0 @@
|
|||
// 7 april 2015
|
||||
#include "uipriv_darwin.h"
|
||||
|
||||
struct singleView {
|
||||
NSView *view;
|
||||
NSScrollView *scrollView;
|
||||
NSView *immediate; // the control that is added to the parent container; either view or scrollView
|
||||
uiContainer *parent;
|
||||
int hidden;
|
||||
int userDisabled;
|
||||
int containerDisabled;
|
||||
void (*onDestroy)(void *);
|
||||
void *onDestroyData;
|
||||
};
|
||||
|
||||
static void singleDestroy(uiControl *c)
|
||||
{
|
||||
struct singleView *s = (struct singleView *) (c->Internal);
|
||||
|
||||
if (s->parent != NULL)
|
||||
complain("attempt to destroy a uiControl at %p while it still has a parent", c);
|
||||
(*(s->onDestroy))(s->onDestroyData);
|
||||
// release the reference we took on creation to destroy the widget
|
||||
[s->immediate release];
|
||||
uiFree(s);
|
||||
}
|
||||
|
||||
static uintptr_t singleHandle(uiControl *c)
|
||||
{
|
||||
struct singleView *s = (struct singleView *) (c->Internal);
|
||||
|
||||
return (uintptr_t) (s->view);
|
||||
}
|
||||
|
||||
static void singleSetParent(uiControl *c, uiContainer *parent)
|
||||
{
|
||||
struct singleView *s = (struct singleView *) (c->Internal);
|
||||
NSView *parentView;
|
||||
uiContainer *oldparent;
|
||||
|
||||
oldparent = s->parent;
|
||||
s->parent = parent;
|
||||
if (oldparent != NULL)
|
||||
[s->immediate removeFromSuperview];
|
||||
if (s->parent != NULL) {
|
||||
parentView = (NSView *) uiControlHandle(uiControl(s->parent));
|
||||
[parentView addSubview:s->immediate];
|
||||
}
|
||||
}
|
||||
|
||||
// also good for NSBox and NSProgressIndicator
|
||||
static void singlePreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
|
||||
{
|
||||
struct singleView *s = (struct singleView *) (c->Internal);
|
||||
NSControl *control;
|
||||
NSRect r;
|
||||
|
||||
control = (NSControl *) (s->view);
|
||||
[control sizeToFit];
|
||||
// use alignmentRect here instead of frame because we'll be resizing based on that
|
||||
r = [control alignmentRectForFrame:[control frame]];
|
||||
*width = (intmax_t) r.size.width;
|
||||
*height = (intmax_t) r.size.height;
|
||||
}
|
||||
|
||||
static void singleResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
|
||||
{
|
||||
struct singleView *s = (struct singleView *) (c->Internal);
|
||||
NSRect frame;
|
||||
|
||||
frame.origin.x = x;
|
||||
// mac os x coordinate system has (0,0) in the lower-left
|
||||
frame.origin.y = ([[s->immediate superview] bounds].size.height - height) - y;
|
||||
frame.size.width = width;
|
||||
frame.size.height = height;
|
||||
frame = [s->immediate frameForAlignmentRect:frame];
|
||||
[s->immediate setFrame:frame];
|
||||
}
|
||||
|
||||
static int singleVisible(uiControl *c)
|
||||
{
|
||||
struct singleView *s = (struct singleView *) (c->Internal);
|
||||
|
||||
return !s->hidden;
|
||||
}
|
||||
|
||||
static void singleShow(uiControl *c)
|
||||
{
|
||||
struct singleView *s = (struct singleView *) (c->Internal);
|
||||
|
||||
[s->immediate setHidden:NO];
|
||||
s->hidden = 0;
|
||||
if (s->parent != NULL)
|
||||
uiContainerUpdate(s->parent);
|
||||
}
|
||||
|
||||
static void singleHide(uiControl *c)
|
||||
{
|
||||
struct singleView *s = (struct singleView *) (c->Internal);
|
||||
|
||||
[s->immediate setHidden:YES];
|
||||
s->hidden = 1;
|
||||
if (s->parent != NULL)
|
||||
uiContainerUpdate(s->parent);
|
||||
}
|
||||
|
||||
static void singleEnable(uiControl *c)
|
||||
{
|
||||
struct singleView *s = (struct singleView *) (c->Internal);
|
||||
|
||||
s->userDisabled = 0;
|
||||
if (!s->containerDisabled)
|
||||
if ([s->view respondsToSelector:@selector(setEnabled:)])
|
||||
[((NSControl *) (s->view)) setEnabled:YES];
|
||||
}
|
||||
|
||||
static void singleDisable(uiControl *c)
|
||||
{
|
||||
struct singleView *s = (struct singleView *) (c->Internal);
|
||||
|
||||
s->userDisabled = 1;
|
||||
if ([s->view respondsToSelector:@selector(setEnabled:)])
|
||||
[((NSControl *) (s->view)) setEnabled:NO];
|
||||
}
|
||||
|
||||
static void singleSysFunc(uiControl *c, uiControlSysFuncParams *p)
|
||||
{
|
||||
struct singleView *s = (struct singleView *) (c->Internal);
|
||||
|
||||
switch (p->Func) {
|
||||
case uiDarwinSysFuncContainerEnable:
|
||||
s->containerDisabled = 0;
|
||||
if (!s->userDisabled)
|
||||
if ([s->view respondsToSelector:@selector(setEnabled:)])
|
||||
[((NSControl *) (s->view)) setEnabled:YES];
|
||||
return;
|
||||
case uiDarwinSysFuncContainerDisable:
|
||||
s->containerDisabled = 1;
|
||||
if ([s->view respondsToSelector:@selector(setEnabled:)])
|
||||
[((NSControl *) (s->view)) setEnabled:NO];
|
||||
return;
|
||||
}
|
||||
complain("unknown p->Func %d in singleSysFunc()", p->Func);
|
||||
}
|
||||
|
||||
void uiDarwinMakeControl(uiControl *c, Class class, BOOL inScrollView, BOOL scrollViewHasBorder, void (*onDestroy)(void *), void *onDestroyData)
|
||||
{
|
||||
struct singleView *s;
|
||||
|
||||
s = uiNew(struct singleView);
|
||||
// thanks to autoxr and arwyn in irc.freenode.net/#macdev
|
||||
s->view = (NSView *) [[class alloc] initWithFrame:NSZeroRect];
|
||||
s->immediate = s->view;
|
||||
|
||||
if (inScrollView) {
|
||||
s->scrollView = [[NSScrollView alloc] initWithFrame:NSZeroRect];
|
||||
[s->scrollView setDocumentView:s->view];
|
||||
[s->scrollView setHasHorizontalScroller:YES];
|
||||
[s->scrollView setHasVerticalScroller:YES];
|
||||
[s->scrollView setAutohidesScrollers:YES];
|
||||
if (scrollViewHasBorder)
|
||||
[s->scrollView setBorderType:NSBezelBorder];
|
||||
else
|
||||
[s->scrollView setBorderType:NSNoBorder];
|
||||
s->immediate = (NSView *) (s->scrollView);
|
||||
}
|
||||
|
||||
s->onDestroy = onDestroy;
|
||||
s->onDestroyData = onDestroyData;
|
||||
|
||||
// and keep a reference to s->immediate for when we remove the control from its parent
|
||||
[s->immediate retain];
|
||||
|
||||
uiControl(c)->Internal = s;
|
||||
uiControl(c)->Destroy = singleDestroy;
|
||||
uiControl(c)->Handle = singleHandle;
|
||||
uiControl(c)->SetParent = singleSetParent;
|
||||
uiControl(c)->PreferredSize = singlePreferredSize;
|
||||
uiControl(c)->Resize = singleResize;
|
||||
uiControl(c)->Visible = singleVisible;
|
||||
uiControl(c)->Show = singleShow;
|
||||
uiControl(c)->Hide = singleHide;
|
||||
uiControl(c)->Enable = singleEnable;
|
||||
uiControl(c)->Disable = singleDisable;
|
||||
uiControl(c)->SysFunc = singleSysFunc;
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
# 28 april 2015
|
||||
|
||||
osMFILES = \
|
||||
darwin/alloc.m \
|
||||
darwin/bin.m \
|
||||
darwin/button.m \
|
||||
darwin/checkbox.m \
|
||||
darwin/combobox.m \
|
||||
darwin/container.m \
|
||||
darwin/control.m \
|
||||
darwin/datetimepicker.m \
|
||||
darwin/entry.m \
|
||||
darwin/group.m \
|
||||
darwin/label.m \
|
||||
darwin/main.m \
|
||||
darwin/menu.m \
|
||||
darwin/progressbar.m \
|
||||
darwin/radiobuttons.m \
|
||||
darwin/separator.m \
|
||||
darwin/slider.m \
|
||||
darwin/spinbox.m \
|
||||
darwin/stddialogs.m \
|
||||
darwin/tab.m \
|
||||
darwin/text.m \
|
||||
darwin/util.m \
|
||||
darwin/window.m
|
||||
|
||||
osHFILES = \
|
||||
darwin/uipriv_darwin.h
|
||||
|
||||
osCFLAGS = \
|
||||
-D_UI_EXTERN='__attribute__((visibility("default"))) extern' \
|
||||
-fvisibility=hidden \
|
||||
-mmacosx-version-min=10.7 -DMACOSX_DEPLOYMENT_TARGET=10.7
|
||||
osLDFLAGS = \
|
||||
-fvisibility=hidden \
|
||||
-mmacosx-version-min=10.7 -lobjc -framework Foundation -framework AppKit
|
||||
|
||||
# the gcc flags don't work with Apple's linker
|
||||
# fortunately, we don't need any; Apple's linker warns about undefined symbols in -shared builds!
|
||||
osLDWarnUndefinedFlags =
|
||||
|
||||
osLIBSUFFIX = .dylib
|
||||
osEXESUFFIX =
|
||||
|
||||
ifeq ($(ARCH),386)
|
||||
archmflag = -m32
|
||||
else
|
||||
archmflag = -m64
|
||||
endif
|
|
@ -1,84 +0,0 @@
|
|||
// 4 december 2014
|
||||
#import <stdlib.h>
|
||||
#import "uipriv_darwin.h"
|
||||
|
||||
NSMutableArray *allocations;
|
||||
|
||||
void initAlloc(void)
|
||||
{
|
||||
allocations = [NSMutableArray new];
|
||||
}
|
||||
|
||||
#define UINT8(p) ((uint8_t *) (p))
|
||||
#define PVOID(p) ((void *) (p))
|
||||
#define EXTRA (sizeof (size_t) + sizeof (const char **))
|
||||
#define DATA(p) PVOID(UINT8(p) + EXTRA)
|
||||
#define BASE(p) PVOID(UINT8(p) - EXTRA)
|
||||
#define SIZE(p) ((size_t *) (p))
|
||||
#define CCHAR(p) ((const char **) (p))
|
||||
#define TYPE(p) CCHAR(UINT8(p) + sizeof (size_t))
|
||||
|
||||
void uninitAlloc(void)
|
||||
{
|
||||
if ([allocations count] == 0) {
|
||||
[allocations release];
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "[libui] leaked allocations:\n");
|
||||
[allocations enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) {
|
||||
NSValue *v;
|
||||
void *ptr;
|
||||
|
||||
v = (NSValue *) obj;
|
||||
ptr = [v pointerValue];
|
||||
fprintf(stderr, "[libui] %p %s\n", ptr, *TYPE(ptr));
|
||||
}];
|
||||
complain("either you left something around or there's a bug in libui");
|
||||
}
|
||||
|
||||
void *uiAlloc(size_t size, const char *type)
|
||||
{
|
||||
void *out;
|
||||
|
||||
out = malloc(EXTRA + size);
|
||||
if (out == NULL) {
|
||||
fprintf(stderr, "memory exhausted in uiAlloc()\n");
|
||||
abort();
|
||||
}
|
||||
memset(DATA(out), 0, size);
|
||||
*SIZE(out) = size;
|
||||
*TYPE(out) = type;
|
||||
[allocations addObject:[NSValue valueWithPointer:out]];
|
||||
return DATA(out);
|
||||
}
|
||||
|
||||
void *uiRealloc(void *p, size_t new, const char *type)
|
||||
{
|
||||
void *out;
|
||||
size_t *s;
|
||||
|
||||
if (p == NULL)
|
||||
return uiAlloc(new, type);
|
||||
p = BASE(p);
|
||||
out = realloc(p, EXTRA + new);
|
||||
if (out == NULL) {
|
||||
fprintf(stderr, "memory exhausted in uiRealloc()\n");
|
||||
abort();
|
||||
}
|
||||
s = SIZE(out);
|
||||
if (new <= *s)
|
||||
memset(((uint8_t *) DATA(out)) + *s, 0, new - *s);
|
||||
*s = new;
|
||||
[allocations removeObject:[NSValue valueWithPointer:p]];
|
||||
[allocations addObject:[NSValue valueWithPointer:out]];
|
||||
return DATA(out);
|
||||
}
|
||||
|
||||
void uiFree(void *p)
|
||||
{
|
||||
if (p == NULL)
|
||||
complain("attempt to uiFree(NULL); there's a bug somewhere");
|
||||
p = BASE(p);
|
||||
free(p);
|
||||
[allocations removeObject:[NSValue valueWithPointer:p]];
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
// 28 april 2015
|
||||
#import "uipriv_darwin.h"
|
||||
|
||||
// This is a uiControl wrapper a la GtkBin on GTK+.
|
||||
// It serves the function of tabPage on Windows: it allows uiWindow and uiTab to give their children a real uiControl as a parent while not screwing with the internal NSView structure of those uiControls.
|
||||
// It also provides margins.
|
||||
|
||||
struct bin {
|
||||
uiControl c;
|
||||
NSView *view;
|
||||
uiControl *child;
|
||||
int margined;
|
||||
NSArray *hconstraint;
|
||||
NSArray *vconstraint;
|
||||
};
|
||||
|
||||
uiDefineControlType(bin, binType, struct bin)
|
||||
|
||||
static uintptr_t binHandle(uiControl *c)
|
||||
{
|
||||
struct bin *b = (struct bin *) c;
|
||||
|
||||
return (uintptr_t) (b->view);
|
||||
}
|
||||
|
||||
uiControl *newBin(void)
|
||||
{
|
||||
struct bin *b;
|
||||
|
||||
b = (struct bin *) uiNewControl(binType());
|
||||
|
||||
// a simple NSView will do fine
|
||||
b->view = [[NSView alloc] initWithFrame:NSZeroRect];
|
||||
uiDarwinMakeSingleViewControl(uiControl(b), b->view, NO);
|
||||
|
||||
uiControl(b)->Handle = binHandle;
|
||||
|
||||
return uiControl(b);
|
||||
}
|
||||
|
||||
void binSetChild(uiControl *c, uiControl *child)
|
||||
{
|
||||
struct bin *b = (struct bin *) c;
|
||||
NSView *binView, *childView;
|
||||
NSDictionary *views;
|
||||
|
||||
binView = (NSView *) uiControlHandle(uiControl(b));
|
||||
if (b->child != NULL) {
|
||||
[binView removeConstraints:b->hconstraint];
|
||||
[binView removeConstraints:b->vconstraint];
|
||||
[b->hconstraint release];
|
||||
[b->vconstraint release];
|
||||
childView = (NSView *) uiControlHandle(b->child);
|
||||
[childView removeFromSuperview];
|
||||
}
|
||||
b->child = child;
|
||||
if (b->child != NULL) {
|
||||
uiControlSetParent(b->child, uiControl(b));
|
||||
childView = (NSView *) uiControlHandle(b->child);
|
||||
[childView setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
views = NSDictionaryOfVariableBindings(childView);
|
||||
b->hconstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[childView]|" options:0 metrics:nil views:views];
|
||||
b->vconstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[childView]|" options:0 metrics:nil views:views];
|
||||
[binView addConstraints:b->hconstraint];
|
||||
[binView addConstraints:b->vconstraint];
|
||||
}
|
||||
}
|
||||
|
||||
int binMargined(uiControl *c)
|
||||
{
|
||||
struct bin *b = (struct bin *) c;
|
||||
|
||||
return b->margined;
|
||||
}
|
||||
|
||||
void binSetMargined(uiControl *c, int margined)
|
||||
{
|
||||
struct bin *b = (struct bin *) c;
|
||||
|
||||
b->margined = margined;
|
||||
// TODO use auto layout
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
// 10 june 2015
|
||||
#include "uipriv_darwin.h"
|
||||
|
||||
// TODO reimplement CommitDestroy() on all of these
|
||||
|
||||
@interface buttonDelegate : NSObject {
|
||||
uiButton *b;
|
||||
void (*onClicked)(uiButton *, void *);
|
||||
void *onClickedData;
|
||||
}
|
||||
- (IBAction)buttonClicked:(id)sender;
|
||||
- (void)setButton:(uiButton *)newb;
|
||||
- (void)setOnClicked:(void (*)(uiButton *, void *))f data:(void *)data;
|
||||
@end
|
||||
|
||||
@implementation buttonDelegate
|
||||
|
||||
- (IBAction)buttonClicked:(id)sender
|
||||
{
|
||||
(*(self->onClicked))(self->b, self->onClickedData);
|
||||
}
|
||||
|
||||
- (void)setButton:(uiButton *)newb
|
||||
{
|
||||
self->b = newb;
|
||||
}
|
||||
|
||||
- (void)setOnClicked:(void (*)(uiButton *, void *))f data:(void *)data
|
||||
{
|
||||
self->onClicked = f;
|
||||
self->onClickedData = data;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
struct button {
|
||||
uiButton b;
|
||||
NSButton *button;
|
||||
buttonDelegate *delegate;
|
||||
};
|
||||
|
||||
uiDefineControlType(uiButton, uiTypeButton, struct button)
|
||||
|
||||
static uintptr_t buttonHandle(uiControl *c)
|
||||
{
|
||||
struct button *b = (struct button *) c;
|
||||
|
||||
return (uintptr_t) (b->button);
|
||||
}
|
||||
|
||||
static void defaultOnClicked(uiButton *b, void *data)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
static char *buttonText(uiButton *bb)
|
||||
{
|
||||
struct button *b = (struct button *) bb;
|
||||
|
||||
return uiDarwinNSStringToText([b->button title]);
|
||||
}
|
||||
|
||||
static void buttonSetText(uiButton *bb, const char *text)
|
||||
{
|
||||
struct button *b = (struct button *) bb;
|
||||
|
||||
[b->button setTitle:toNSString(text)];
|
||||
}
|
||||
|
||||
static void buttonOnClicked(uiButton *bb, void (*f)(uiButton *, void *), void *data)
|
||||
{
|
||||
struct button *b = (struct button *) bb;
|
||||
|
||||
[b->delegate setOnClicked:f data:data];
|
||||
}
|
||||
|
||||
uiButton *uiNewButton(const char *text)
|
||||
{
|
||||
struct button *b;
|
||||
|
||||
b = (struct button *) uiNewControl(uiTypeButton());
|
||||
|
||||
b->button = [[NSButton alloc] initWithFrame:NSZeroRect];
|
||||
[b->button setTitle:toNSString(text)];
|
||||
[b->button setButtonType:NSMomentaryPushInButton];
|
||||
[b->button setBordered:YES];
|
||||
[b->button setBezelStyle:NSRoundedBezelStyle];
|
||||
uiDarwinMakeSingleViewControl(uiControl(b), b->button, YES);
|
||||
|
||||
b->delegate = [buttonDelegate new];
|
||||
[b->button setTarget:b->delegate];
|
||||
[b->button setAction:@selector(buttonClicked:)];
|
||||
[b->delegate setButton:uiButton(b)];
|
||||
[b->delegate setOnClicked:defaultOnClicked data:NULL];
|
||||
|
||||
uiControl(b)->Handle = buttonHandle;
|
||||
|
||||
uiButton(b)->Text = buttonText;
|
||||
uiButton(b)->SetText = buttonSetText;
|
||||
uiButton(b)->OnClicked = buttonOnClicked;
|
||||
|
||||
return uiButton(b);
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
// 10 june 2015
|
||||
#include "uipriv_darwin.h"
|
||||
|
||||
@interface checkboxDelegate : NSObject {
|
||||
uiCheckbox *c;
|
||||
void (*onToggled)(uiCheckbox *, void *);
|
||||
void *onToggledData;
|
||||
}
|
||||
- (IBAction)checkboxToggled:(id)sender;
|
||||
- (void)setCheckbox:(uiCheckbox *)newc;
|
||||
- (void)setOnToggled:(void (*)(uiCheckbox *, void *))f data:(void *)data;
|
||||
@end
|
||||
|
||||
@implementation checkboxDelegate
|
||||
|
||||
- (IBAction)checkboxToggled:(id)sender
|
||||
{
|
||||
(*(self->onToggled))(self->c, self->onToggledData);
|
||||
}
|
||||
|
||||
- (void)setCheckbox:(uiCheckbox *)newc
|
||||
{
|
||||
self->c = newc;
|
||||
}
|
||||
|
||||
- (void)setOnToggled:(void (*)(uiCheckbox *, void *))f data:(void *)data
|
||||
{
|
||||
self->onToggled = f;
|
||||
self->onToggledData = data;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
struct checkbox {
|
||||
uiCheckbox c;
|
||||
NSButton *checkbox;
|
||||
checkboxDelegate *delegate;
|
||||
};
|
||||
|
||||
uiDefineControlType(uiCheckbox, uiTypeCheckbox, struct checkbox)
|
||||
|
||||
static uintptr_t checkboxHandle(uiControl *cc)
|
||||
{
|
||||
struct checkbox *c = (struct checkbox *) cc;
|
||||
|
||||
return (uintptr_t) (c->checkbox);
|
||||
}
|
||||
|
||||
static void defaultOnToggled(uiCheckbox *c, void *data)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
static char *checkboxText(uiCheckbox *cc)
|
||||
{
|
||||
struct checkbox *c = (struct checkbox *) cc;
|
||||
|
||||
return uiDarwinNSStringToText([c->checkbox title]);
|
||||
}
|
||||
|
||||
static void checkboxSetText(uiCheckbox *cc, const char *text)
|
||||
{
|
||||
struct checkbox *c = (struct checkbox *) cc;
|
||||
|
||||
[c->checkbox setTitle:toNSString(text)];
|
||||
}
|
||||
|
||||
static void checkboxOnToggled(uiCheckbox *cc, void (*f)(uiCheckbox *, void *), void *data)
|
||||
{
|
||||
struct checkbox *c = (struct checkbox *) cc;
|
||||
|
||||
[c->delegate setOnToggled:f data:data];
|
||||
}
|
||||
|
||||
static int checkboxChecked(uiCheckbox *cc)
|
||||
{
|
||||
struct checkbox *c = (struct checkbox *) cc;
|
||||
|
||||
return [c->checkbox state] == NSOnState;
|
||||
}
|
||||
|
||||
static void checkboxSetChecked(uiCheckbox *cc, int checked)
|
||||
{
|
||||
struct checkbox *c = (struct checkbox *) cc;
|
||||
NSInteger state;
|
||||
|
||||
state = NSOnState;
|
||||
if (!checked)
|
||||
state = NSOffState;
|
||||
[c->checkbox setState:state];
|
||||
}
|
||||
|
||||
uiCheckbox *uiNewCheckbox(const char *text)
|
||||
{
|
||||
struct checkbox *c;
|
||||
|
||||
c = (struct checkbox *) uiNewControl(uiTypeCheckbox());
|
||||
|
||||
// TODO make a macro for the below
|
||||
c->checkbox = [[NSButton alloc] initWithFrame:NSZeroRect];
|
||||
[c->checkbox setTitle:toNSString(text)];
|
||||
[c->checkbox setButtonType:NSSwitchButton];
|
||||
[c->checkbox setBordered:NO];
|
||||
uiDarwinMakeSingleViewControl(uiControl(c), c->checkbox, YES);
|
||||
|
||||
c->delegate = [checkboxDelegate new];
|
||||
[c->checkbox setTarget:c->delegate];
|
||||
[c->checkbox setAction:@selector(checkboxToggled:)];
|
||||
[c->delegate setCheckbox:uiCheckbox(c)];
|
||||
[c->delegate setOnToggled:defaultOnToggled data:NULL];
|
||||
|
||||
uiControl(c)->Handle = checkboxHandle;
|
||||
|
||||
uiCheckbox(c)->Text = checkboxText;
|
||||
uiCheckbox(c)->SetText = checkboxSetText;
|
||||
uiCheckbox(c)->OnToggled = checkboxOnToggled;
|
||||
uiCheckbox(c)->Checked = checkboxChecked;
|
||||
uiCheckbox(c)->SetChecked = checkboxSetChecked;
|
||||
|
||||
return uiCheckbox(c);
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
// 11 june 2015
|
||||
#include "uipriv_darwin.h"
|
||||
|
||||
struct combobox {
|
||||
uiCombobox c;
|
||||
BOOL editable;
|
||||
NSPopUpButton *pb;
|
||||
NSComboBox *cb;
|
||||
};
|
||||
|
||||
uiDefineControlType(uiCombobox, uiTypeCombobox, struct combobox)
|
||||
|
||||
static uintptr_t comboboxHandle(uiControl *cc)
|
||||
{
|
||||
struct combobox *c = (struct combobox *) cc;
|
||||
|
||||
if (c->editable)
|
||||
return (uintptr_t) (c->cb);
|
||||
return (uintptr_t) (c->pb);
|
||||
}
|
||||
|
||||
static void comboboxAppend(uiCombobox *cc, const char *text)
|
||||
{
|
||||
struct combobox *c = (struct combobox *) cc;
|
||||
|
||||
PUT_CODE_HERE;
|
||||
}
|
||||
|
||||
static uiCombobox *finishNewCombobox(BOOL editable)
|
||||
{
|
||||
struct combobox *c;
|
||||
|
||||
c = (struct combobox *) uiNewControl(uiTypeCombobox());
|
||||
|
||||
c->editable = editable;
|
||||
if (c->editable) {
|
||||
c->cb = [[NSComboBox alloc] initWithFrame:NSZeroRect];
|
||||
[c->cb setUsesDataSource:NO];
|
||||
[c->cb setButtonBordered:YES];
|
||||
[c->cb setCompletes:NO];
|
||||
uiDarwinMakeSingleViewControl(uiControl(c), c->cb, YES);
|
||||
} else {
|
||||
c->pb = [[NSPopUpButton alloc] initWithFrame:NSZeroRect pullsDown:NO];
|
||||
// TODO preferred edge
|
||||
// TODO arrow position
|
||||
// TODO font
|
||||
uiDarwinMakeSingleViewControl(uiControl(c), c->cb, YES);
|
||||
}
|
||||
|
||||
uiControl(c)->Handle = comboboxHandle;
|
||||
|
||||
uiCombobox(c)->Append = comboboxAppend;
|
||||
|
||||
return uiCombobox(c);
|
||||
}
|
||||
|
||||
uiCombobox *uiNewCombobox(void)
|
||||
{
|
||||
return finishNewCombobox(NO);
|
||||
}
|
||||
|
||||
uiCombobox *uiNewEditableCombobox(void)
|
||||
{
|
||||
return finishNewCombobox(YES);
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
// 28 april 2015
|
||||
#import "uipriv_darwin.h"
|
||||
|
||||
@interface containerView : NSView {
|
||||
uiControl *c;
|
||||
}
|
||||
- (void)setContainer:(uiControl *)cc;
|
||||
- (void)containerUpdate;
|
||||
@end
|
||||
|
||||
@implementation containerView
|
||||
|
||||
- (void)setContainer:(uiControl *)cc
|
||||
{
|
||||
self->c = cc;
|
||||
}
|
||||
|
||||
- (void)containerUpdate
|
||||
{
|
||||
uiSizing *d;
|
||||
intmax_t x, y, width, height;
|
||||
|
||||
x = [self bounds].origin.x;
|
||||
y = [self bounds].origin.y;
|
||||
width = [self bounds].size.width;
|
||||
height = [self bounds].size.height;
|
||||
d = uiDarwinNewSizing();
|
||||
uiControlResize(self->c, x, y, width, height, d);
|
||||
}
|
||||
|
||||
- (void)setFrameSize:(NSSize)s
|
||||
{
|
||||
[super setFrameSize:s];
|
||||
[self containerUpdate];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
uintptr_t uiMakeContainer(uiControl *c)
|
||||
{
|
||||
containerView *view;
|
||||
|
||||
view = [[containerView alloc] initWithFrame:NSZeroRect];
|
||||
uiDarwinMakeSingleViewControl(c, view, NO);
|
||||
[view setContainer:c];
|
||||
return (uintptr_t) view;
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
// 11 june 2015
|
||||
#include "uipriv_darwin.h"
|
||||
|
||||
#define VIEW(c) ((NSView *) uiControlHandle((c)))
|
||||
|
||||
static void singleViewCommitDestroy(uiControl *c)
|
||||
{
|
||||
// TODO make this unnecessary?
|
||||
if ([VIEW(c) respondsToSelector:@selector(delegate)])
|
||||
[[VIEW(c) delegate] release];
|
||||
[VIEW(c) release];
|
||||
}
|
||||
|
||||
static void singleViewCommitSetParent(uiControl *c, uiControl *parent)
|
||||
{
|
||||
if (parent == NULL) {
|
||||
[VIEW(c) removeFromSuperview];
|
||||
return;
|
||||
}
|
||||
[VIEW(parent) addSubview:VIEW(c)];
|
||||
}
|
||||
|
||||
static void singleViewPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
|
||||
{
|
||||
NSView *v;
|
||||
NSRect r;
|
||||
|
||||
v = VIEW(c);
|
||||
if (![v respondsToSelector:@selector(sizeToFit)])
|
||||
complain("uiControl %p does not respond to -sizeToFit; its type needs to provide an implementation of uiControlPreferredSize()", c);
|
||||
[v sizeToFit];
|
||||
// use alignmentRect here instead of frame because we'll be resizing based on that
|
||||
r = [v alignmentRectForFrame:[v frame]];
|
||||
*width = (intmax_t) r.size.width;
|
||||
*height = (intmax_t) r.size.height;
|
||||
}
|
||||
|
||||
static void singleViewResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
|
||||
{
|
||||
NSRect r;
|
||||
|
||||
r.origin.x = x;
|
||||
// mac os x coordinate system has (0,0) in the lower-left
|
||||
r.origin.y = ([[VIEW(c) superview] bounds].size.height - height) - y;
|
||||
r.size.width = width;
|
||||
r.size.height = height;
|
||||
// this is the size of the alignment rect; the frame can be bigger (see NSButton)
|
||||
r = [VIEW(c) frameForAlignmentRect:r];
|
||||
[VIEW(c) setFrame:r];
|
||||
}
|
||||
|
||||
static uiSizing *singleViewSizing(uiControl *c)
|
||||
{
|
||||
return uiDarwinNewSizing();
|
||||
}
|
||||
|
||||
static void singleViewCommitShow(uiControl *c)
|
||||
{
|
||||
[VIEW(c) setHidden:NO];
|
||||
}
|
||||
|
||||
static void singleViewCommitHide(uiControl *c)
|
||||
{
|
||||
[VIEW(c) setHidden:YES];
|
||||
}
|
||||
|
||||
static void singleViewCommitEnable(uiControl *c)
|
||||
{
|
||||
NSControl *cc;
|
||||
|
||||
if ([VIEW(c) respondsToSelector:@selector(setEnabled:)]) {
|
||||
// use NSControl to avoid compiler warnings
|
||||
cc = (NSControl *) VIEW(c);
|
||||
[cc setEnabled:YES];
|
||||
}
|
||||
}
|
||||
|
||||
static void singleViewCommitDisable(uiControl *c)
|
||||
{
|
||||
NSControl *cc;
|
||||
|
||||
if ([VIEW(c) respondsToSelector:@selector(setEnabled:)]) {
|
||||
// use NSControl to avoid compiler warnings
|
||||
cc = (NSControl *) VIEW(c);
|
||||
[cc setEnabled:NO];
|
||||
}
|
||||
}
|
||||
|
||||
static uintptr_t singleViewStartZOrder(uiControl *c)
|
||||
{
|
||||
// we don't need to do anything; Cocoa does it for us
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uintptr_t singleViewSetZOrder(uiControl *c, uintptr_t insertAfter)
|
||||
{
|
||||
// we don't need to do anything; Cocoa does it for us
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int singleViewHasTabStops(uiControl *c)
|
||||
{
|
||||
complain("singleViewHasTabStops() meaningless on OS X");
|
||||
return 0; // keep compiler happy
|
||||
}
|
||||
|
||||
// called after creating the control's NSView
|
||||
void uiDarwinMakeSingleViewControl(uiControl *c, NSView *view, BOOL useStandardControlFont)
|
||||
{
|
||||
// we have to retain the view so we can reparent it
|
||||
[view retain];
|
||||
|
||||
if (useStandardControlFont)
|
||||
setStandardControlFont((NSControl *) view);
|
||||
|
||||
uiControl(c)->CommitDestroy = singleViewCommitDestroy;
|
||||
uiControl(c)->CommitSetParent = singleViewCommitSetParent;
|
||||
uiControl(c)->PreferredSize = singleViewPreferredSize;
|
||||
uiControl(c)->Resize = singleViewResize;
|
||||
uiControl(c)->Sizing = singleViewSizing;
|
||||
uiControl(c)->CommitShow = singleViewCommitShow;
|
||||
uiControl(c)->CommitHide = singleViewCommitHide;
|
||||
uiControl(c)->CommitEnable = singleViewCommitEnable;
|
||||
uiControl(c)->CommitDisable = singleViewCommitDisable;
|
||||
uiControl(c)->StartZOrder = singleViewStartZOrder;
|
||||
uiControl(c)->SetZOrder = singleViewSetZOrder;
|
||||
uiControl(c)->HasTabStops = singleViewHasTabStops;
|
||||
}
|
||||
|
||||
void queueResize(uiControl *c)
|
||||
{
|
||||
// TODO
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
// 11 june 2015
|
||||
#include "uipriv_darwin.h"
|
||||
|
||||
struct datetimepicker {
|
||||
uiDateTimePicker d;
|
||||
NSDatePicker *dp;
|
||||
};
|
||||
|
||||
uiDefineControlType(uiDateTimePicker, uiTypeDateTimePicker, struct datetimepicker)
|
||||
|
||||
static uintptr_t datetimepickerHandle(uiControl *c)
|
||||
{
|
||||
struct datetimepicker *d = (struct datetimepicker *) c;
|
||||
|
||||
return (uintptr_t) (d->dp);
|
||||
}
|
||||
|
||||
uiDateTimePicker *finishNewDateTimePicker(NSDatePickerElementFlags elements)
|
||||
{
|
||||
struct datetimepicker *d;
|
||||
|
||||
d = (struct datetimepicker *) uiNewControl(uiTypeDateTimePicker());
|
||||
|
||||
d->dp = [[NSDatePicker alloc] initWithFrame:NSZeroRect];
|
||||
// TODO text field stuff
|
||||
[d->dp setDatePickerStyle:NSTextFieldAndStepperDatePickerStyle];
|
||||
[d->dp setDatePickerElements:elements];
|
||||
[d->dp setDatePickerMode:NSSingleDateMode];
|
||||
// TODO get date picker font
|
||||
uiDarwinMakeSingleViewControl(uiControl(d), d->dp, YES);
|
||||
|
||||
uiControl(d)->Handle = datetimepickerHandle;
|
||||
|
||||
return uiDateTimePicker(d);
|
||||
}
|
||||
|
||||
uiDateTimePicker *uiNewDateTimePicker(void)
|
||||
{
|
||||
return finishNewDateTimePicker(NSYearMonthDayDatePickerElementFlag | NSHourMinuteSecondDatePickerElementFlag);
|
||||
}
|
||||
|
||||
uiDateTimePicker *uiNewDatePicker(void)
|
||||
{
|
||||
return finishNewDateTimePicker(NSYearMonthDayDatePickerElementFlag);
|
||||
}
|
||||
|
||||
uiDateTimePicker *uiNewTimePicker(void)
|
||||
{
|
||||
return finishNewDateTimePicker(NSHourMinuteSecondDatePickerElementFlag);
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
// 11 june 2015
|
||||
#include "uipriv_darwin.h"
|
||||
|
||||
@interface entryDelegate : NSObject <NSTextFieldDelegate> {
|
||||
uiEntry *e;
|
||||
void (*onChanged)(uiEntry *, void *);
|
||||
void *onChangedData;
|
||||
}
|
||||
- (void)controlTextDidChange:(NSNotification *)note;
|
||||
- (void)setEntry:(uiEntry *)newe;
|
||||
- (void)setOnChanged:(void (*)(uiEntry *, void *))f data:(void *)data;
|
||||
@end
|
||||
|
||||
@implementation entryDelegate
|
||||
|
||||
- (void)controlTextDidChange:(NSNotification *)note
|
||||
{
|
||||
(*(self->onChanged))(self->e, self->onChangedData);
|
||||
}
|
||||
|
||||
- (void)setEntry:(uiEntry *)newe
|
||||
{
|
||||
self->e = newe;
|
||||
}
|
||||
|
||||
- (void)setOnChanged:(void (*)(uiEntry *, void *))f data:(void *)data
|
||||
{
|
||||
self->onChanged = f;
|
||||
self->onChangedData = data;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
struct entry {
|
||||
uiEntry e;
|
||||
NSTextField *textfield;
|
||||
entryDelegate *delegate;
|
||||
};
|
||||
|
||||
uiDefineControlType(uiEntry, uiTypeEntry, struct entry)
|
||||
|
||||
static uintptr_t entryHandle(uiControl *c)
|
||||
{
|
||||
struct entry *e = (struct entry *) c;
|
||||
|
||||
return (uintptr_t) (e->textfield);
|
||||
}
|
||||
|
||||
static void defaultOnChanged(uiEntry *e, void *data)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
static char *entryText(uiEntry *ee)
|
||||
{
|
||||
struct entry *e = (struct entry *) ee;
|
||||
|
||||
return uiDarwinNSStringToText([e->textfield stringValue]);
|
||||
}
|
||||
|
||||
static void entrySetText(uiEntry *ee, const char *text)
|
||||
{
|
||||
struct entry *e = (struct entry *) ee;
|
||||
|
||||
[e->textfield setStringValue:toNSString(text)];
|
||||
// don't queue the control for resize; entry sizes are independent of their contents
|
||||
}
|
||||
|
||||
static void entryOnChanged(uiEntry *ee, void (*f)(uiEntry *, void *), void *data)
|
||||
{
|
||||
struct entry *e = (struct entry *) ee;
|
||||
|
||||
[e->delegate setOnChanged:f data:data];
|
||||
}
|
||||
|
||||
static int entryReadOnly(uiEntry *ee)
|
||||
{
|
||||
struct entry *e = (struct entry *) ee;
|
||||
|
||||
return [e->textfield isEditable] == NO;
|
||||
}
|
||||
|
||||
static void entrySetReadOnly(uiEntry *ee, int readonly)
|
||||
{
|
||||
struct entry *e = (struct entry *) ee;
|
||||
BOOL editable;
|
||||
|
||||
editable = YES;
|
||||
if (readonly)
|
||||
editable = NO;
|
||||
[e->textfield setEditable:editable];
|
||||
}
|
||||
|
||||
// these are based on interface builder defaults; my comments in the old code weren't very good so I don't really know what talked about what, sorry :/
|
||||
void finishNewTextField(uiControl *tt, NSTextField *t, BOOL isEntry)
|
||||
{
|
||||
uiDarwinMakeSingleViewControl(tt, t, YES);
|
||||
|
||||
// THE ORDER OF THESE CALLS IS IMPORTANT; CHANGE IT AND THE BORDERS WILL DISAPPEAR
|
||||
[t setBordered:NO];
|
||||
[t setBezelStyle:NSTextFieldSquareBezel];
|
||||
[t setBezeled:isEntry];
|
||||
|
||||
// we don't need to worry about substitutions/autocorrect here; see window_darwin.m for details
|
||||
|
||||
[[t cell] setLineBreakMode:NSLineBreakByClipping];
|
||||
[[t cell] setScrollable:YES];
|
||||
}
|
||||
|
||||
uiEntry *uiNewEntry(void)
|
||||
{
|
||||
struct entry *e;
|
||||
|
||||
e = (struct entry *) uiNewControl(uiTypeEntry());
|
||||
|
||||
e->textfield = [[NSTextField alloc] initWithFrame:NSZeroRect];
|
||||
|
||||
[e->textfield setSelectable:YES]; // otherwise the setting is masked by the editable default of YES
|
||||
finishNewTextField(uiControl(e), e->textfield, YES);
|
||||
|
||||
e->delegate = [entryDelegate new];
|
||||
[e->textfield setDelegate:e->delegate];
|
||||
[e->delegate setEntry:uiEntry(e)];
|
||||
[e->delegate setOnChanged:defaultOnChanged data:NULL];
|
||||
|
||||
uiControl(e)->Handle = entryHandle;
|
||||
|
||||
uiEntry(e)->Text = entryText;
|
||||
uiEntry(e)->SetText = entrySetText;
|
||||
uiEntry(e)->OnChanged = entryOnChanged;
|
||||
uiEntry(e)->ReadOnly = entryReadOnly;
|
||||
uiEntry(e)->SetReadOnly = entrySetReadOnly;
|
||||
|
||||
return uiEntry(e);
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
// 11 june 2015
|
||||
#include "uipriv_darwin.h"
|
||||
|
||||
struct group {
|
||||
uiGroup g;
|
||||
NSBox *box;
|
||||
uiControl *child;
|
||||
int margined;
|
||||
};
|
||||
|
||||
uiDefineControlType(uiGroup, uiTypeGroup, struct group)
|
||||
|
||||
static uintptr_t groupHandle(uiControl *c)
|
||||
{
|
||||
struct group *g = (struct group *) c;
|
||||
|
||||
return (uintptr_t) (g->box);
|
||||
}
|
||||
|
||||
static void groupContainerUpdateState(uiControl *c)
|
||||
{
|
||||
struct group *g = (struct group *) c;
|
||||
|
||||
if (g->child != NULL)
|
||||
uiControlUpdateState(g->child);
|
||||
}
|
||||
|
||||
static char *groupTitle(uiGroup *gg)
|
||||
{
|
||||
struct group *g = (struct group *) gg;
|
||||
|
||||
return PUT_CODE_HERE;
|
||||
}
|
||||
|
||||
static void groupSetTitle(uiGroup *gg, const char *text)
|
||||
{
|
||||
struct group *g = (struct group *) gg;
|
||||
|
||||
PUT_CODE_HERE;
|
||||
// changing the text might necessitate a change in the groupbox's size
|
||||
uiControlQueueResize(uiControl(g));
|
||||
}
|
||||
|
||||
static void groupSetChild(uiGroup *gg, uiControl *child)
|
||||
{
|
||||
struct group *g = (struct group *) gg;
|
||||
|
||||
if (g->child != NULL)
|
||||
uiControlSetParent(g->child, NULL);
|
||||
g->child = child;
|
||||
if (g->child != NULL) {
|
||||
uiControlSetParent(g->child, uiControl(g));
|
||||
uiControlQueueResize(g->child);
|
||||
}
|
||||
}
|
||||
|
||||
static int groupMargined(uiGroup *gg)
|
||||
{
|
||||
struct group *g = (struct group *) gg;
|
||||
|
||||
return g->margined;
|
||||
}
|
||||
|
||||
static void groupSetMargined(uiGroup *gg, int margined)
|
||||
{
|
||||
struct group *g = (struct group *) gg;
|
||||
|
||||
g->margined = margined;
|
||||
uiControlQueueResize(uiControl(g));
|
||||
}
|
||||
|
||||
uiGroup *uiNewGroup(const char *text)
|
||||
{
|
||||
struct group *g;
|
||||
|
||||
g = (struct group *) uiNewControl(uiTypeGroup());
|
||||
|
||||
g->box = [[NSBox alloc] initWithFrame:NSZeroRect];
|
||||
[g->box setBoxType:NSBoxPrimary];
|
||||
//TODO [g->box setBorderType:TODO];
|
||||
[g->box setTransparent:NO];
|
||||
[g->box setTitlePosition:NSAtTop];
|
||||
|
||||
// can't set title font the way the function does; plus we need to use a different size
|
||||
uiDarwinMakeSingleViewControl(uiControl(g), g->box, NO);
|
||||
// TODO verify if Small in Xcode is this small
|
||||
[g->box setTitleFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]];
|
||||
|
||||
uiControl(g)->Handle = groupHandle;
|
||||
uiControl(g)->ContainerUpdateState = groupContainerUpdateState;
|
||||
|
||||
uiGroup(g)->Title = groupTitle;
|
||||
uiGroup(g)->SetTitle = groupSetTitle;
|
||||
uiGroup(g)->SetChild = groupSetChild;
|
||||
uiGroup(g)->Margined = groupMargined;
|
||||
uiGroup(g)->SetMargined = groupSetMargined;
|
||||
|
||||
return uiGroup(g);
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
// 11 june 2015
|
||||
#include "uipriv_darwin.h"
|
||||
|
||||
struct label {
|
||||
uiLabel l;
|
||||
NSTextField *label;
|
||||
};
|
||||
|
||||
uiDefineControlType(uiLabel, uiTypeLabel, struct label)
|
||||
|
||||
static uintptr_t labelHandle(uiControl *c)
|
||||
{
|
||||
struct label *l = (struct label *) c;
|
||||
|
||||
return (uintptr_t) (l->label);
|
||||
}
|
||||
|
||||
static char *labelText(uiLabel *ll)
|
||||
{
|
||||
struct label *l = (struct label *) ll;
|
||||
|
||||
return uiDarwinNSStringToText([l->label stringValue]);
|
||||
}
|
||||
|
||||
static void labelSetText(uiLabel *ll, const char *text)
|
||||
{
|
||||
struct label *l = (struct label *) ll;
|
||||
|
||||
[l->label setStringValue:toNSString(text)];
|
||||
// changing the text might necessitate a change in the label's size
|
||||
uiControlQueueResize(uiControl(l));
|
||||
}
|
||||
|
||||
uiLabel *uiNewLabel(const char *text)
|
||||
{
|
||||
struct label *l;
|
||||
|
||||
l = (struct label *) uiNewControl(uiTypeLabel());
|
||||
|
||||
l->label = [[NSTextField alloc] initWithFrame:NSZeroRect];
|
||||
|
||||
[l->label setStringValue:toNSString(text)];
|
||||
[l->label setEditable:NO];
|
||||
[l->label setSelectable:NO];
|
||||
[l->label setDrawsBackground:NO];
|
||||
finishNewTextField(uiControl(l), l->label, NO);
|
||||
|
||||
uiControl(l)->Handle = labelHandle;
|
||||
|
||||
uiLabel(l)->Text = labelText;
|
||||
uiLabel(l)->SetText = labelSetText;
|
||||
|
||||
return uiLabel(l);
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
// 6 april 2015
|
||||
#import "uipriv_darwin.h"
|
||||
|
||||
static BOOL canQuit = NO;
|
||||
|
||||
@implementation applicationClass
|
||||
|
||||
// hey look! we're overriding terminate:!
|
||||
// we're going to make sure we can go back to main() whether Cocoa likes it or not!
|
||||
// and just how are we going to do that, hm?
|
||||
// (note: this is called after applicationShouldTerminate:)
|
||||
- (void)terminate:(id)sender
|
||||
{
|
||||
// yes that's right folks: DO ABSOLUTELY NOTHING.
|
||||
// the magic is [NSApp run] will just... stop.
|
||||
|
||||
// well let's not do nothing; let's actually quit our graceful way
|
||||
NSEvent *e;
|
||||
|
||||
// for debugging
|
||||
NSLog(@"in terminate:");
|
||||
|
||||
if (!canQuit)
|
||||
complain("call to [NSApp terminate:] when not ready to terminate");
|
||||
|
||||
[realNSApp() stop:realNSApp()];
|
||||
// stop: won't register until another event has passed; let's synthesize one
|
||||
e = [NSEvent otherEventWithType:NSApplicationDefined
|
||||
location:NSZeroPoint
|
||||
modifierFlags:0
|
||||
timestamp:[[NSProcessInfo processInfo] systemUptime]
|
||||
windowNumber:0
|
||||
context:[NSGraphicsContext currentContext]
|
||||
subtype:0
|
||||
data1:0
|
||||
data2:0];
|
||||
[realNSApp() postEvent:e atStart:NO]; // let pending events take priority (this is what PostQuitMessage() on Windows does so we have to do it here too for parity; thanks to mikeash in irc.freenode.net/#macdev for confirming that this parameter should indeed be NO)
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation appDelegate
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self.menuManager release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app
|
||||
{
|
||||
// for debugging
|
||||
NSLog(@"in applicationShouldTerminate:");
|
||||
if (shouldQuit()) {
|
||||
canQuit = YES;
|
||||
// this will call terminate:, which is the same as uiQuit()
|
||||
return NSTerminateNow;
|
||||
}
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
uiInitOptions options;
|
||||
|
||||
const char *uiInit(uiInitOptions *o)
|
||||
{
|
||||
options = *o;
|
||||
[applicationClass sharedApplication];
|
||||
// don't check for a NO return; something (launch services?) causes running from application bundles to always return NO when asking to change activation policy, even if the change is to the same activation policy!
|
||||
// see https://github.com/andlabs/ui/issues/6
|
||||
[realNSApp() setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
[realNSApp() setDelegate:[appDelegate new]];
|
||||
|
||||
initAlloc();
|
||||
|
||||
// always do this so we always have an application menu
|
||||
appDelegate().menuManager = [menuManager new];
|
||||
[realNSApp() setMainMenu:[appDelegate().menuManager makeMenubar]];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void uiUninit(void)
|
||||
{
|
||||
uninitMenus();
|
||||
// TODO free application delegate
|
||||
// TODO free NSApplication resources (main menu, etc.)
|
||||
uninitAlloc();
|
||||
}
|
||||
|
||||
void uiFreeInitError(const char *err)
|
||||
{
|
||||
}
|
||||
|
||||
void uiMain(void)
|
||||
{
|
||||
[realNSApp() run];
|
||||
}
|
||||
|
||||
void uiQuit(void)
|
||||
{
|
||||
canQuit = YES;
|
||||
[realNSApp() terminate:realNSApp()];
|
||||
}
|
|
@ -1,384 +0,0 @@
|
|||
// 28 april 2015
|
||||
#import "uipriv_darwin.h"
|
||||
|
||||
static NSMutableArray *menus = nil;
|
||||
static BOOL menusFinalized = NO;
|
||||
|
||||
struct menu {
|
||||
uiMenu m;
|
||||
NSMenu *menu;
|
||||
NSMenuItem *item;
|
||||
NSMutableArray *items;
|
||||
};
|
||||
|
||||
struct menuItem {
|
||||
uiMenuItem mi;
|
||||
NSMenuItem *item;
|
||||
int type;
|
||||
BOOL disabled;
|
||||
void (*onClicked)(uiMenuItem *, uiWindow *, void *);
|
||||
void *onClickedData;
|
||||
};
|
||||
|
||||
enum {
|
||||
typeRegular,
|
||||
typeCheckbox,
|
||||
typeQuit,
|
||||
typePreferences,
|
||||
typeAbout,
|
||||
typeSeparator,
|
||||
};
|
||||
|
||||
@implementation menuManager
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
// TODO NSPointerFunctionsOpaquePersonality?
|
||||
self->items = [NSMapTable mapTableWithKeyOptions:NSPointerFunctionsOpaqueMemory
|
||||
valueOptions:NSPointerFunctionsOpaqueMemory];
|
||||
self->hasQuit = NO;
|
||||
self->hasPreferences = NO;
|
||||
self->hasAbout = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self->items release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (IBAction)onClicked:(id)sender
|
||||
{
|
||||
struct menuItem *item;
|
||||
NSValue *v;
|
||||
|
||||
v = (NSValue *) [self->items objectForKey:sender];
|
||||
item = (struct menuItem *) [v pointerValue];
|
||||
if (item->type == typeCheckbox)
|
||||
uiMenuItemSetChecked(uiMenuItem(item), !uiMenuItemChecked(uiMenuItem(item)));
|
||||
// use the key window as the source of the menu event; it's the active window
|
||||
(*(item->onClicked))(uiMenuItem(item), windowFromNSWindow([realNSApp() keyWindow]), item->onClickedData);
|
||||
}
|
||||
|
||||
- (IBAction)onQuitClicked:(id)sender
|
||||
{
|
||||
if (shouldQuit())
|
||||
uiQuit();
|
||||
}
|
||||
|
||||
- (void)register:(NSMenuItem *)item to:(struct menuItem *)smi
|
||||
{
|
||||
NSValue *v;
|
||||
|
||||
switch (smi->type) {
|
||||
case typeQuit:
|
||||
if (self->hasQuit)
|
||||
complain("attempt to add multiple Quit menu items");
|
||||
self->hasQuit = YES;
|
||||
break;
|
||||
case typePreferences:
|
||||
if (self->hasPreferences)
|
||||
complain("attempt to add multiple Preferences menu items");
|
||||
self->hasPreferences = YES;
|
||||
break;
|
||||
case typeAbout:
|
||||
if (self->hasAbout)
|
||||
complain("attempt to add multiple About menu items");
|
||||
self->hasAbout = YES;
|
||||
break;
|
||||
}
|
||||
v = [NSValue valueWithPointer:smi];
|
||||
[self->items setObject:v forKey:item];
|
||||
}
|
||||
|
||||
// on OS X there are two ways to handle menu items being enabled or disabled: automatically and manually
|
||||
// unfortunately, the application menu requires automatic menu handling for the Hide, Hide Others, and Show All items to work correctly
|
||||
// therefore, we have to handle enabling of the other options ourselves
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item
|
||||
{
|
||||
struct menuItem *smi;
|
||||
NSValue *v;
|
||||
|
||||
// disable the special items if they aren't present
|
||||
if (item == self.quitItem && !self->hasQuit)
|
||||
return NO;
|
||||
if (item == self.preferencesItem && !self->hasPreferences)
|
||||
return NO;
|
||||
if (item == self.aboutItem && !self->hasAbout)
|
||||
return NO;
|
||||
// then poll the item's enabled/disabled state
|
||||
v = (NSValue *) [self->items objectForKey:item];
|
||||
smi = (struct menuItem *) [v pointerValue];
|
||||
return !smi->disabled;
|
||||
}
|
||||
|
||||
// Cocoa constructs the default application menu by hand for each program; that's what MainMenu.[nx]ib does
|
||||
- (void)buildApplicationMenu:(NSMenu *)menubar
|
||||
{
|
||||
NSString *appName;
|
||||
NSMenuItem *appMenuItem;
|
||||
NSMenu *appMenu;
|
||||
NSMenuItem *item;
|
||||
NSString *title;
|
||||
NSMenu *servicesMenu;
|
||||
|
||||
appName = [[NSProcessInfo processInfo] processName];
|
||||
appMenuItem = [[NSMenuItem alloc] initWithTitle:appName action:NULL keyEquivalent:@""];
|
||||
appMenu = [[NSMenu alloc] initWithTitle:appName];
|
||||
[appMenuItem setSubmenu:appMenu];
|
||||
[menubar addItem:appMenuItem];
|
||||
|
||||
// first is About
|
||||
title = [@"About " stringByAppendingString:appName];
|
||||
item = [[NSMenuItem alloc] initWithTitle:title action:@selector(onClicked:) keyEquivalent:@""];
|
||||
[item setTarget:self];
|
||||
[appMenu addItem:item];
|
||||
self.aboutItem = item;
|
||||
|
||||
[appMenu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
// next is Preferences
|
||||
item = [[NSMenuItem alloc] initWithTitle:@"Preferences…" action:@selector(onClicked:) keyEquivalent:@","];
|
||||
[item setTarget:self];
|
||||
[appMenu addItem:item];
|
||||
self.preferencesItem = item;
|
||||
|
||||
[appMenu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
// next is Services
|
||||
item = [[NSMenuItem alloc] initWithTitle:@"Services" action:NULL keyEquivalent:@""];
|
||||
servicesMenu = [[NSMenu alloc] initWithTitle:@"Services"];
|
||||
[item setSubmenu:servicesMenu];
|
||||
[realNSApp() setServicesMenu:servicesMenu];
|
||||
[appMenu addItem:item];
|
||||
|
||||
[appMenu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
// next are the three hiding options
|
||||
title = [@"Hide " stringByAppendingString:appName];
|
||||
item = [[NSMenuItem alloc] initWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
|
||||
// the .xib file says they go to -1 ("First Responder", which sounds wrong...)
|
||||
// to do that, we simply leave the target as nil
|
||||
[appMenu addItem:item];
|
||||
item = [[NSMenuItem alloc] initWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
|
||||
[item setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)];
|
||||
[appMenu addItem:item];
|
||||
item = [[NSMenuItem alloc] initWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
|
||||
[appMenu addItem:item];
|
||||
|
||||
[appMenu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
// and finally Quit
|
||||
// DON'T use @selector(terminate:) as the action; we handle termination ourselves
|
||||
title = [@"Quit " stringByAppendingString:appName];
|
||||
item = [[NSMenuItem alloc] initWithTitle:title action:@selector(onQuitClicked:) keyEquivalent:@"q"];
|
||||
[item setTarget:self];
|
||||
[appMenu addItem:item];
|
||||
self.quitItem = item;
|
||||
}
|
||||
|
||||
- (NSMenu *)makeMenubar
|
||||
{
|
||||
NSMenu *menubar;
|
||||
|
||||
menubar = [[NSMenu alloc] initWithTitle:@""];
|
||||
[self buildApplicationMenu:menubar];
|
||||
return menubar;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static void defaultOnClicked(uiMenuItem *item, uiWindow *w, void *data)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
static void menuItemEnable(uiMenuItem *ii)
|
||||
{
|
||||
struct menuItem *item = (struct menuItem *) ii;
|
||||
|
||||
item->disabled = NO;
|
||||
// we don't need to explicitly update the menus here; they'll be updated the next time they're opened (thanks mikeash in irc.freenode.net/#macdev)
|
||||
}
|
||||
|
||||
static void menuItemDisable(uiMenuItem *ii)
|
||||
{
|
||||
struct menuItem *item = (struct menuItem *) ii;
|
||||
|
||||
item->disabled = YES;
|
||||
}
|
||||
|
||||
static void menuItemOnClicked(uiMenuItem *ii, void (*f)(uiMenuItem *, uiWindow *, void *), void *data)
|
||||
{
|
||||
struct menuItem *item = (struct menuItem *) ii;
|
||||
|
||||
if (item->type == typeQuit)
|
||||
complain("attempt to call uiMenuItemOnClicked() on a Quit item; use uiOnShouldQuit() instead");
|
||||
item->onClicked = f;
|
||||
item->onClickedData = data;
|
||||
}
|
||||
|
||||
static int menuItemChecked(uiMenuItem *ii)
|
||||
{
|
||||
struct menuItem *item = (struct menuItem *) ii;
|
||||
|
||||
return [item->item state] != NSOffState;
|
||||
}
|
||||
|
||||
static void menuItemSetChecked(uiMenuItem *ii, int checked)
|
||||
{
|
||||
struct menuItem *item = (struct menuItem *) ii;
|
||||
NSInteger state;
|
||||
|
||||
state = NSOffState;
|
||||
if ([item->item state] == NSOffState)
|
||||
state = NSOnState;
|
||||
[item->item setState:state];
|
||||
}
|
||||
|
||||
static uiMenuItem *newItem(struct menu *m, int type, const char *name)
|
||||
{
|
||||
struct menuItem *item;
|
||||
|
||||
if (menusFinalized)
|
||||
complain("attempt to create a new menu item after menus have been finalized");
|
||||
|
||||
item = uiNew(struct menuItem);
|
||||
uiTyped(item)->Type = uiTypeMenuItem();
|
||||
|
||||
item->type = type;
|
||||
switch (item->type) {
|
||||
case typeQuit:
|
||||
item->item = appDelegate().menuManager.quitItem;
|
||||
break;
|
||||
case typePreferences:
|
||||
item->item = appDelegate().menuManager.preferencesItem;
|
||||
break;
|
||||
case typeAbout:
|
||||
item->item = appDelegate().menuManager.aboutItem;
|
||||
break;
|
||||
case typeSeparator:
|
||||
item->item = [NSMenuItem separatorItem];
|
||||
[m->menu addItem:item->item];
|
||||
break;
|
||||
default:
|
||||
item->item = [[NSMenuItem alloc] initWithTitle:toNSString(name) action:@selector(onClicked:) keyEquivalent:@""];
|
||||
[item->item setTarget:appDelegate().menuManager];
|
||||
[m->menu addItem:item->item];
|
||||
break;
|
||||
}
|
||||
|
||||
[appDelegate().menuManager register:item->item to:item];
|
||||
item->onClicked = defaultOnClicked;
|
||||
|
||||
[m->items addObject:[NSValue valueWithPointer:item]];
|
||||
|
||||
uiMenuItem(item)->Enable = menuItemEnable;
|
||||
uiMenuItem(item)->Disable = menuItemDisable;
|
||||
uiMenuItem(item)->OnClicked = menuItemOnClicked;
|
||||
uiMenuItem(item)->Checked = menuItemChecked;
|
||||
uiMenuItem(item)->SetChecked = menuItemSetChecked;
|
||||
|
||||
return uiMenuItem(item);
|
||||
}
|
||||
|
||||
static uiMenuItem *menuAppendItem(uiMenu *mm, const char *name)
|
||||
{
|
||||
return newItem((struct menu *) mm, typeRegular, name);
|
||||
}
|
||||
|
||||
static uiMenuItem *menuAppendCheckItem(uiMenu *mm, const char *name)
|
||||
{
|
||||
return newItem((struct menu *) mm, typeCheckbox, name);
|
||||
}
|
||||
|
||||
static uiMenuItem *menuAppendQuitItem(uiMenu *mm)
|
||||
{
|
||||
// duplicate check is in the register:to: selector
|
||||
return newItem((struct menu *) mm, typeQuit, NULL);
|
||||
}
|
||||
|
||||
static uiMenuItem *menuAppendPreferencesItem(uiMenu *mm)
|
||||
{
|
||||
// duplicate check is in the register:to: selector
|
||||
return newItem((struct menu *) mm, typePreferences, NULL);
|
||||
}
|
||||
|
||||
static uiMenuItem *menuAppendAboutItem(uiMenu *mm)
|
||||
{
|
||||
// duplicate check is in the register:to: selector
|
||||
return newItem((struct menu *) mm, typeAbout, NULL);
|
||||
}
|
||||
|
||||
static void menuAppendSeparator(uiMenu *mm)
|
||||
{
|
||||
newItem((struct menu *) mm, typeSeparator, NULL);
|
||||
}
|
||||
|
||||
uiMenu *uiNewMenu(const char *name)
|
||||
{
|
||||
struct menu *m;
|
||||
|
||||
if (menusFinalized)
|
||||
complain("attempt to create a new menu after menus have been finalized");
|
||||
if (menus == nil)
|
||||
menus = [NSMutableArray new];
|
||||
|
||||
m = uiNew(struct menu);
|
||||
uiTyped(m)->Type = uiTypeMenu();
|
||||
|
||||
m->menu = [[NSMenu alloc] initWithTitle:toNSString(name)];
|
||||
// use automatic menu item enabling for all menus for consistency's sake
|
||||
|
||||
m->item = [[NSMenuItem alloc] initWithTitle:toNSString(name) action:NULL keyEquivalent:@""];
|
||||
[m->item setSubmenu:m->menu];
|
||||
|
||||
m->items = [NSMutableArray new];
|
||||
|
||||
[[realNSApp() mainMenu] addItem:m->item];
|
||||
|
||||
[menus addObject:[NSValue valueWithPointer:m]];
|
||||
|
||||
uiMenu(m)->AppendItem = menuAppendItem;
|
||||
uiMenu(m)->AppendCheckItem = menuAppendCheckItem;
|
||||
uiMenu(m)->AppendQuitItem = menuAppendQuitItem;
|
||||
uiMenu(m)->AppendPreferencesItem = menuAppendPreferencesItem;
|
||||
uiMenu(m)->AppendAboutItem = menuAppendAboutItem;
|
||||
uiMenu(m)->AppendSeparator = menuAppendSeparator;
|
||||
|
||||
return uiMenu(m);
|
||||
}
|
||||
|
||||
void finalizeMenus(void)
|
||||
{
|
||||
menusFinalized = YES;
|
||||
}
|
||||
|
||||
void uninitMenus(void)
|
||||
{
|
||||
if (menus == NULL)
|
||||
return;
|
||||
// don't worry about the actual NSMenus and NSMenuItems; they'll be freed when we clean up the NSApplication
|
||||
[menus enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) {
|
||||
NSValue *v;
|
||||
struct menu *m;
|
||||
|
||||
v = (NSValue *) obj;
|
||||
m = (struct menu *) [v pointerValue];
|
||||
[m->items enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) {
|
||||
NSValue *v;
|
||||
struct menuItem *mi;
|
||||
|
||||
v = (NSValue *) obj;
|
||||
mi = (struct menuItem *) [v pointerValue];
|
||||
uiFree(mi);
|
||||
}];
|
||||
[m->items release];
|
||||
uiFree(m);
|
||||
}];
|
||||
[menus release];
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
// 11 june 2015
|
||||
#include "uipriv_darwin.h"
|
||||
|
||||
struct progressbar {
|
||||
uiProgressBar p;
|
||||
NSProgressIndicator *pi;
|
||||
};
|
||||
|
||||
uiDefineControlType(uiProgressBar, uiTypeProgressBar, struct progressbar)
|
||||
|
||||
static uintptr_t progressbarHandle(uiControl *c)
|
||||
{
|
||||
struct progressbar *p = (struct progressbar *) c;
|
||||
|
||||
return (uintptr_t) (p->pi);
|
||||
}
|
||||
|
||||
static void progressbarSetValue(uiProgressBar *pp, int value)
|
||||
{
|
||||
struct progressbar *p = (struct progressbar *) pp;
|
||||
|
||||
if (value < 0 || value > 100)
|
||||
complain("value %d out of range in progressbarSetValue()", value);
|
||||
PUT_CODE_HERE;
|
||||
}
|
||||
|
||||
uiProgressBar *uiNewProgressBar(void)
|
||||
{
|
||||
struct progressbar *p;
|
||||
|
||||
p = (struct progressbar *) uiNewControl(uiTypeProgressBar());
|
||||
|
||||
p->pi = [[NSProgressIndicator alloc] initWithFrame:NSZeroRect];
|
||||
[p->pi setControlSize:NSRegularControlSize];
|
||||
[p->pi setBezeled:YES];
|
||||
[p->pi setStyle:NSProgressIndicatorBarStyle];
|
||||
[p->pi setIndeterminate:NO];
|
||||
uiDarwinMakeSingleViewControl(uiControl(p), p->pi, NO);
|
||||
|
||||
uiControl(p)->Handle = progressbarHandle;
|
||||
|
||||
uiProgressBar(p)->SetValue = progressbarSetValue;
|
||||
|
||||
return uiProgressBar(p);
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
// 11 june 2015
|
||||
#include "uipriv_darwin.h"
|
||||
|
||||
struct radiobuttons {
|
||||
uiRadioButtons r;
|
||||
NSTextField *dummy;
|
||||
};
|
||||
|
||||
uiDefineControlType(uiRadioButtons, uiTypeRadioButtons, struct radiobuttons)
|
||||
|
||||
static uintptr_t radiobuttonsHandle(uiControl *c)
|
||||
{
|
||||
struct radiobuttons *r = (struct radiobuttons *) c;
|
||||
|
||||
return (uintptr_t) (r->dummy);
|
||||
}
|
||||
|
||||
static void radiobuttonsAppend(uiRadioButtons *rr, const char *text)
|
||||
{
|
||||
struct radiobuttons *r = (struct radiobuttons *) rr;
|
||||
|
||||
PUT_CODE_HERE;
|
||||
uiControlQueueResize(uiControl(r));
|
||||
}
|
||||
|
||||
uiRadioButtons *uiNewRadioButtons(void)
|
||||
{
|
||||
struct radiobuttons *r;
|
||||
|
||||
r = (struct radiobuttons *) uiNewControl(uiTypeRadioButtons());
|
||||
|
||||
r->dummy = [[NSTextField alloc] initWithFrame:NSZeroRect];
|
||||
[r->dummy setStringValue:@"TODO uiRadioButtons not implemented"];
|
||||
uiDarwinMakeSingleViewControl(uiControl(r), r->dummy, YES);
|
||||
|
||||
uiControl(r)->Handle = radiobuttonsHandle;
|
||||
|
||||
uiRadioButtons(r)->Append = radiobuttonsAppend;
|
||||
|
||||
return uiRadioButtons(r);
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
// 11 june 2015
|
||||
#include "uipriv_darwin.h"
|
||||
|
||||
// TODO sizing
|
||||
|
||||
struct separator {
|
||||
uiSeparator s;
|
||||
NSBox *box;
|
||||
};
|
||||
|
||||
uiDefineControlType(uiSeparator, uiTypeSeparator, struct separator)
|
||||
|
||||
static uintptr_t separatorHandle(uiControl *c)
|
||||
{
|
||||
struct separator *s = (struct separator *) c;
|
||||
|
||||
return (uintptr_t) (s->box);
|
||||
}
|
||||
|
||||
uiSeparator *uiNewHorizontalSeparator(void)
|
||||
{
|
||||
struct separator *s;
|
||||
|
||||
s = (struct separator *) uiNewControl(uiTypeSeparator());
|
||||
|
||||
s->box = [[NSBox alloc] initWithFrame:NSZeroRect];
|
||||
[s->box setBoxType:NSBoxSeparator];
|
||||
//TODO [s->box setBorderType:TODO];
|
||||
[s->box setTransparent:NO];
|
||||
[s->box setTitlePosition:NSNoTitle];
|
||||
|
||||
uiDarwinMakeSingleViewControl(uiControl(s), s->box, NO);
|
||||
|
||||
uiControl(s)->Handle = separatorHandle;
|
||||
|
||||
return uiSeparator(s);
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
// 11 june 2015
|
||||
#include "uipriv_darwin.h"
|
||||
|
||||
// TODO events
|
||||
|
||||
struct slider {
|
||||
uiSlider s;
|
||||
NSSlider *slider;
|
||||
void (*onChanged)(uiSlider *, void *);
|
||||
void *onChangedData;
|
||||
};
|
||||
|
||||
uiDefineControlType(uiSlider, uiTypeSlider, struct slider)
|
||||
|
||||
static uintptr_t sliderHandle(uiControl *c)
|
||||
{
|
||||
struct slider *s = (struct slider *) c;
|
||||
|
||||
return (uintptr_t) (s->slider);
|
||||
}
|
||||
|
||||
static void defaultOnChanged(uiSlider *s, void *data)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
static intmax_t sliderValue(uiSlider *ss)
|
||||
{
|
||||
struct slider *s = (struct slider *) ss;
|
||||
|
||||
return PUT_CODE_HERE;
|
||||
}
|
||||
|
||||
static void sliderSetValue(uiSlider *ss, intmax_t value)
|
||||
{
|
||||
struct slider *s = (struct slider *) ss;
|
||||
|
||||
PUT_CODE_HERE;
|
||||
}
|
||||
|
||||
static void sliderOnChanged(uiSlider *ss, void (*f)(uiSlider *, void *), void *data)
|
||||
{
|
||||
struct slider *s = (struct slider *) ss;
|
||||
|
||||
s->onChanged = f;
|
||||
s->onChangedData = data;
|
||||
}
|
||||
|
||||
uiSlider *uiNewSlider(intmax_t min, intmax_t max)
|
||||
{
|
||||
struct slider *s;
|
||||
NSSliderCell *cell;
|
||||
|
||||
s = (struct slider *) uiNewControl(uiTypeSlider());
|
||||
|
||||
s->slider = [[NSSlider alloc] initWithFrame:NSZeroRect];
|
||||
// TODO vertical is defined by wider than tall
|
||||
[s->slider setMinValue:min];
|
||||
[s->slider setMaxValue:max];
|
||||
[s->slider setAllowsTickMarkValuesOnly:NO];
|
||||
[s->slider setNumberOfTickMarks:0];
|
||||
[s->slider setTickMarkPosition:NSTickMarkAbove];
|
||||
|
||||
cell = (NSSliderCell *) [s->slider cell];
|
||||
[cell setSliderType:NSLinearSlider];
|
||||
|
||||
uiDarwinMakeSingleViewControl(uiControl(s), s->slider, NO);
|
||||
|
||||
s->onChanged = defaultOnChanged;
|
||||
|
||||
uiControl(s)->Handle = sliderHandle;
|
||||
|
||||
uiSlider(s)->Value = sliderValue;
|
||||
uiSlider(s)->SetValue = sliderSetValue;
|
||||
uiSlider(s)->OnChanged = sliderOnChanged;
|
||||
|
||||
return uiSlider(s);
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
// 11 june 2015
|
||||
#include "uipriv_darwin.h"
|
||||
|
||||
struct spinbox {
|
||||
uiSpinbox s;
|
||||
NSTextField *dummy;
|
||||
void (*onChanged)(uiSpinbox *, void *);
|
||||
void *onChangedData;
|
||||
};
|
||||
|
||||
uiDefineControlType(uiSpinbox, uiTypeSpinbox, struct spinbox)
|
||||
|
||||
static uintptr_t spinboxHandle(uiControl *c)
|
||||
{
|
||||
struct spinbox *s = (struct spinbox *) c;
|
||||
|
||||
return (uintptr_t) (s->dummy);
|
||||
}
|
||||
|
||||
static void defaultOnChanged(uiSpinbox *s, void *data)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
static intmax_t spinboxValue(uiSpinbox *ss)
|
||||
{
|
||||
struct spinbox *s = (struct spinbox *) ss;
|
||||
|
||||
return PUT_CODE_HERE;
|
||||
}
|
||||
|
||||
static void spinboxSetValue(uiSpinbox *ss, intmax_t value)
|
||||
{
|
||||
struct spinbox *s = (struct spinbox *) ss;
|
||||
|
||||
PUT_CODE_HERE;
|
||||
}
|
||||
|
||||
static void spinboxOnChanged(uiSpinbox *ss, void (*f)(uiSpinbox *, void *), void *data)
|
||||
{
|
||||
struct spinbox *s = (struct spinbox *) ss;
|
||||
|
||||
s->onChanged = f;
|
||||
s->onChangedData = data;
|
||||
}
|
||||
|
||||
uiSpinbox *uiNewSpinbox(intmax_t min, intmax_t max)
|
||||
{
|
||||
struct spinbox *s;
|
||||
|
||||
if (min >= max)
|
||||
complain("error: min >= max in uiNewSpinbox()");
|
||||
|
||||
s = (struct spinbox *) uiNewControl(uiTypeSpinbox());
|
||||
|
||||
s->dummy = [[NSTextField alloc] initWithFrame:NSZeroRect];
|
||||
[s->dummy setStringValue:@"TODO uiSpinbox not implemented"];
|
||||
uiDarwinMakeSingleViewControl(uiControl(s), s->dummy, YES);
|
||||
|
||||
s->onChanged = defaultOnChanged;
|
||||
|
||||
uiControl(s)->Handle = spinboxHandle;
|
||||
|
||||
uiSpinbox(s)->Value = spinboxValue;
|
||||
uiSpinbox(s)->SetValue = spinboxSetValue;
|
||||
uiSpinbox(s)->OnChanged = spinboxOnChanged;
|
||||
|
||||
return uiSpinbox(s);
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
// 26 june 2015
|
||||
#import "uipriv_darwin.h"
|
||||
|
||||
char *uiOpenFile(void)
|
||||
{
|
||||
// TODO
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *uiSaveFile(void)
|
||||
{
|
||||
// TODO
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void uiMsgBox(const char *title, const char *description)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void uiMsgBoxError(const char *title, const char *description)
|
||||
{
|
||||
// TODO
|
||||
}
|
|
@ -1,206 +0,0 @@
|
|||
// 11 june 2015
|
||||
#include "uipriv_darwin.h"
|
||||
|
||||
// TODO rewrite this whole file to take advantage of what we used to call bin functions
|
||||
|
||||
struct tab {
|
||||
uiTab t;
|
||||
NSTabView *tabview;
|
||||
NSMutableArray *pages;
|
||||
NSMutableArray *margined;
|
||||
void (*baseCommitDestroy)(uiControl *);
|
||||
};
|
||||
|
||||
uiDefineControlType(uiTab, uiTypeTab, struct tab)
|
||||
|
||||
static void tabCommitDestroy(uiControl *c)
|
||||
{
|
||||
struct tab *t = (struct tab *) c;
|
||||
|
||||
// first destroy all tab pages so we can destroy all the bins
|
||||
while ([t->tabview numberOfTabViewItems] != 0)
|
||||
[t->tabview removeTabViewItem:[t->tabview tabViewItemAtIndex:0]];
|
||||
// then destroy all the bins, destroying children in the process
|
||||
// the above loop serves the purpose of binSetParent()
|
||||
[t->pages enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) {
|
||||
NSValue *v = (NSValue *) obj;
|
||||
uiControl *bin;
|
||||
|
||||
bin = (uiControl *) [v pointerValue];
|
||||
binSetChild(bin, NULL);
|
||||
// TODO destroy the child
|
||||
uiControlDestroy(uiControl(bin));
|
||||
}];
|
||||
// and finally destroy ourselves
|
||||
[t->pages release];
|
||||
[t->margined release];
|
||||
(*(t->baseCommitDestroy))(uiControl(t));
|
||||
}
|
||||
|
||||
static uintptr_t tabHandle(uiControl *c)
|
||||
{
|
||||
struct tab *t = (struct tab *) c;
|
||||
|
||||
return (uintptr_t) (t->tabview);
|
||||
}
|
||||
|
||||
// the default new control implementation uses -sizeToFit, which we don't have with NSTabView
|
||||
// fortunately, we do have -minimumSize
|
||||
static void tabPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
|
||||
{
|
||||
struct tab *t = (struct tab *) c;
|
||||
NSSize s;
|
||||
|
||||
s = [t->tabview minimumSize];
|
||||
*width = (intmax_t) (s.width);
|
||||
*height = (intmax_t) (s.height);
|
||||
}
|
||||
|
||||
static void tabContainerUpdateState(uiControl *c)
|
||||
{
|
||||
struct tab *t = (struct tab *) c;
|
||||
|
||||
// TODO enumerate over page CONTROLS instead
|
||||
[t->pages enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) {
|
||||
NSValue *v = (NSValue *) obj;
|
||||
uiControl *bin;
|
||||
|
||||
bin = (uiControl *) [v pointerValue];
|
||||
// TODO get the right function
|
||||
uiControlUpdateState(uiControl(bin));
|
||||
}];
|
||||
}
|
||||
|
||||
// TODO merge with InsertAt
|
||||
static void tabAppend(uiTab *tt, const char *name, uiControl *child)
|
||||
{
|
||||
struct tab *t = (struct tab *) tt;
|
||||
uiControl *page;
|
||||
NSTabViewItem *i;
|
||||
|
||||
page = newBin();
|
||||
binSetChild(page, child);
|
||||
[t->pages addObject:[NSValue valueWithPointer:page]];
|
||||
[t->margined addObject:[NSNumber numberWithInt:0]];
|
||||
|
||||
i = [[NSTabViewItem alloc] initWithIdentifier:nil];
|
||||
[i setLabel:toNSString(name)];
|
||||
[i setView:((NSView *) uiControlHandle(uiControl(page)))];
|
||||
[t->tabview addTabViewItem:i];
|
||||
}
|
||||
|
||||
static void tabInsertAt(uiTab *tt, const char *name, uintmax_t n, uiControl *child)
|
||||
{
|
||||
struct tab *t = (struct tab *) tt;
|
||||
uiControl *page;
|
||||
NSTabViewItem *i;
|
||||
|
||||
page = newBin();
|
||||
binSetChild(page, child);
|
||||
[t->pages insertObject:[NSValue valueWithPointer:page] atIndex:n];
|
||||
[t->margined insertObject:[NSNumber numberWithInt:0] atIndex:n];
|
||||
|
||||
i = [[NSTabViewItem alloc] initWithIdentifier:nil];
|
||||
[i setLabel:toNSString(name)];
|
||||
[i setView:((NSView *) uiControlHandle(uiControl(page)))];
|
||||
[t->tabview insertTabViewItem:i atIndex:n];
|
||||
}
|
||||
|
||||
static void tabDelete(uiTab *tt, uintmax_t n)
|
||||
{
|
||||
struct tab *t = (struct tab *) tt;
|
||||
NSValue *v;
|
||||
uiControl *page;
|
||||
NSTabViewItem *i;
|
||||
|
||||
v = (NSValue *) [t->pages objectAtIndex:n];
|
||||
page = (uiControl *) [v pointerValue];
|
||||
[t->pages removeObjectAtIndex:n];
|
||||
[t->margined removeObjectAtIndex:n];
|
||||
|
||||
// make sure the children of the tab aren't destroyed
|
||||
binSetChild(page, NULL);
|
||||
|
||||
// remove the bin from the tab view
|
||||
// this serves the purpose of uiControlSetOSParent(bin, NULL)
|
||||
i = [t->tabview tabViewItemAtIndex:n];
|
||||
[t->tabview removeTabViewItem:i];
|
||||
|
||||
// then destroy the bin
|
||||
uiControlDestroy(uiControl(page));
|
||||
}
|
||||
|
||||
static uintmax_t tabNumPages(uiTab *tt)
|
||||
{
|
||||
struct tab *t = (struct tab *) tt;
|
||||
|
||||
return [t->pages count];
|
||||
}
|
||||
|
||||
static int tabMargined(uiTab *tt, uintmax_t n)
|
||||
{
|
||||
struct tab *t = (struct tab *) tt;
|
||||
NSNumber *v;
|
||||
|
||||
v = (NSNumber *) [t->margined objectAtIndex:n];
|
||||
return [v intValue];
|
||||
}
|
||||
|
||||
// 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...
|
||||
#define tabLeftMargin 17
|
||||
#define tabTopMargin 3
|
||||
#define tabRightMargin 17
|
||||
#define tabBottomMargin 17
|
||||
|
||||
// notes:
|
||||
// top margin of a tab to its parent should be 12, not 20
|
||||
// our system doesn't allow this...
|
||||
|
||||
static void tabSetMargined(uiTab *tt, uintmax_t n, int margined)
|
||||
{
|
||||
struct tab *t = (struct tab *) tt;
|
||||
NSNumber *v;
|
||||
NSValue *pagev;
|
||||
uiControl *page;
|
||||
|
||||
v = [NSNumber numberWithInt:margined];
|
||||
[t->margined replaceObjectAtIndex:n withObject:v];
|
||||
pagev = (NSValue *) [t->pages objectAtIndex:n];
|
||||
page = (uiControl *) [pagev pointerValue];
|
||||
/* TODO
|
||||
if ([v intValue])
|
||||
uiBinSetMargins(page, tabLeftMargin, tabTopMargin, tabRightMargin, tabBottomMargin);
|
||||
else
|
||||
uiBinSetMargins(page, 0, 0, 0, 0);
|
||||
*/
|
||||
}
|
||||
|
||||
uiTab *uiNewTab(void)
|
||||
{
|
||||
struct tab *t;
|
||||
|
||||
t = (struct tab *) uiNewControl(uiTypeTab());
|
||||
|
||||
t->tabview = [[NSTabView alloc] initWithFrame:NSZeroRect];
|
||||
// also good for NSTabView (same selector and everything)
|
||||
uiDarwinMakeSingleViewControl(uiControl(t), t->tabview, YES);
|
||||
|
||||
t->pages = [NSMutableArray new];
|
||||
t->margined = [NSMutableArray new];
|
||||
|
||||
uiControl(t)->Handle = tabHandle;
|
||||
uiControl(t)->PreferredSize = tabPreferredSize;
|
||||
t->baseCommitDestroy = uiControl(t)->CommitDestroy;
|
||||
uiControl(t)->CommitDestroy = tabCommitDestroy;
|
||||
uiControl(t)->ContainerUpdateState = tabContainerUpdateState;
|
||||
|
||||
uiTab(t)->Append = tabAppend;
|
||||
uiTab(t)->InsertAt = tabInsertAt;
|
||||
uiTab(t)->Delete = tabDelete;
|
||||
uiTab(t)->NumPages = tabNumPages;
|
||||
uiTab(t)->Margined = tabMargined;
|
||||
uiTab(t)->SetMargined = tabSetMargined;
|
||||
|
||||
return uiTab(t);
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
// 10 april 2015
|
||||
#import "uipriv_darwin.h"
|
||||
|
||||
char *uiDarwinNSStringToText(NSString *s)
|
||||
{
|
||||
char *out;
|
||||
|
||||
out = strdup([s UTF8String]);
|
||||
if (out == NULL) {
|
||||
fprintf(stderr, "memory exhausted in uiDarwinNSStringToText()\n");
|
||||
abort();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void uiFreeText(char *s)
|
||||
{
|
||||
free(s);
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
// 6 january 2015
|
||||
#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_7
|
||||
#define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_X_VERSION_10_7
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "../out/ui.h"
|
||||
#import "../ui_darwin.h"
|
||||
#import "../uipriv.h"
|
||||
|
||||
#define toNSString(str) [NSString stringWithUTF8String:(str)]
|
||||
#define fromNSString(str) [(str) UTF8String]
|
||||
|
||||
// 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...
|
||||
#define macXMargin 20
|
||||
#define macYMargin 20
|
||||
|
||||
// menu.m
|
||||
@interface menuManager : NSObject {
|
||||
// unfortunately NSMutableDictionary copies its keys, meaning we can't use it for pointers
|
||||
NSMapTable *items;
|
||||
BOOL hasQuit;
|
||||
BOOL hasPreferences;
|
||||
BOOL hasAbout;
|
||||
}
|
||||
@property (strong) NSMenuItem *quitItem;
|
||||
@property (strong) NSMenuItem *preferencesItem;
|
||||
@property (strong) NSMenuItem *aboutItem;
|
||||
// NSMenuValidation is only informal
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item;
|
||||
- (NSMenu *)makeMenubar;
|
||||
@end
|
||||
extern void finalizeMenus(void);
|
||||
extern void uninitMenus(void);
|
||||
|
||||
// init.m
|
||||
@interface applicationClass : NSApplication
|
||||
@end
|
||||
// this is needed because NSApp is of type id, confusing clang
|
||||
#define realNSApp() ((applicationClass *) NSApp)
|
||||
@interface appDelegate : NSObject <NSApplicationDelegate>
|
||||
@property (strong) menuManager *menuManager;
|
||||
@end
|
||||
#define appDelegate() ((appDelegate *) [realNSApp() delegate])
|
||||
|
||||
// util.m
|
||||
extern void setStandardControlFont(NSControl *);
|
||||
extern void disableAutocorrect(NSTextView *);
|
||||
|
||||
// entry.m
|
||||
extern void finishNewTextField(uiControl *, NSTextField *, BOOL);
|
||||
|
||||
// window.m
|
||||
extern uiWindow *windowFromNSWindow(NSWindow *);
|
||||
|
||||
// alloc.m
|
||||
extern void initAlloc(void);
|
||||
extern void uninitAlloc(void);
|
||||
|
||||
// bin.c
|
||||
extern uiControl *newBin(void);
|
||||
extern void binSetChild(uiControl *, uiControl *);
|
||||
extern int binMargined(uiControl *);
|
||||
extern void binSetMargined(uiControl *, int);
|
||||
|
||||
// TODO
|
||||
#define PUT_CODE_HERE 0
|
|
@ -1,56 +0,0 @@
|
|||
// 7 april 2015
|
||||
#import "uipriv_darwin.h"
|
||||
|
||||
// also fine for NSCells and NSTexts (NSTextViews)
|
||||
void setStandardControlFont(NSControl *control)
|
||||
{
|
||||
[control setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]]];
|
||||
}
|
||||
|
||||
void disableAutocorrect(NSTextView *tv)
|
||||
{
|
||||
[tv setEnabledTextCheckingTypes:0];
|
||||
[tv setAutomaticDashSubstitutionEnabled:NO];
|
||||
// don't worry about automatic data detection; it won't change stringValue (thanks pretty_function in irc.freenode.net/#macdev)
|
||||
[tv setAutomaticSpellingCorrectionEnabled:NO];
|
||||
[tv setAutomaticTextReplacementEnabled:NO];
|
||||
[tv setAutomaticQuoteSubstitutionEnabled:NO];
|
||||
[tv setAutomaticLinkDetectionEnabled:NO];
|
||||
[tv setSmartInsertDeleteEnabled:NO];
|
||||
}
|
||||
|
||||
void complain(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
fprintf(stderr, "[libui] ");
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(ap);
|
||||
abort();
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
uiSizing *uiDarwinNewSizing(void)
|
||||
{
|
||||
uiSizing *d;
|
||||
|
||||
d = uiNew(uiSizing);
|
||||
d->XPadding = macXPadding;
|
||||
d->YPadding = macYPadding;
|
||||
d->Sys = uiNew(uiSizingSys);
|
||||
return d;
|
||||
}
|
||||
|
||||
void uiFreeSizing(uiSizing *d)
|
||||
{
|
||||
uiFree(d->Sys);
|
||||
uiFree(d);
|
||||
}
|
|
@ -1,213 +0,0 @@
|
|||
// 28 april 2015
|
||||
#import "uipriv_darwin.h"
|
||||
|
||||
@interface windowDelegate : NSObject <NSWindowDelegate> {
|
||||
uiWindow *w;
|
||||
int (*onClosing)(uiWindow *, void *);
|
||||
void *onClosingData;
|
||||
}
|
||||
- (uiWindow *)getuiWindow;
|
||||
- (void)setuiWindow:(uiWindow *)ww;
|
||||
- (void)setOnClosing:(int (*)(uiWindow *, void *))f data:(void *)data;
|
||||
@end
|
||||
|
||||
@implementation windowDelegate
|
||||
|
||||
- (uiWindow *)getuiWindow
|
||||
{
|
||||
return self->w;
|
||||
}
|
||||
|
||||
- (void)setuiWindow:(uiWindow *)ww
|
||||
{
|
||||
self->w = ww;
|
||||
}
|
||||
|
||||
- (void)setOnClosing:(int (*)(uiWindow *, void *))f data:(void *)data
|
||||
{
|
||||
self->onClosing = f;
|
||||
self->onClosingData = data;
|
||||
}
|
||||
|
||||
- (BOOL)windowShouldClose:(id)sender
|
||||
{
|
||||
if ((*(self->onClosing))(self->w, self->onClosingData))
|
||||
uiControlDestroy(uiControl(self->w));
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
struct window {
|
||||
uiWindow w;
|
||||
NSWindow *window;
|
||||
windowDelegate *delegate;
|
||||
uiControl *bin;
|
||||
uiControl *child;
|
||||
};
|
||||
|
||||
uiDefineControlType(uiWindow, uiTypeWindow, struct window)
|
||||
|
||||
static int defaultOnClosing(uiWindow *w, void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void windowCommitDestroy(uiControl *c)
|
||||
{
|
||||
struct window *w = (struct window *) c;
|
||||
|
||||
// first hide ourselves
|
||||
[w->window orderOut:w->window];
|
||||
// now destroy the child
|
||||
binSetChild(w->bin, NULL);
|
||||
if (w->child != NULL)
|
||||
uiControlDestroy(w->child);
|
||||
// now destroy the bin
|
||||
// we do this by changing the content view to a dummy view
|
||||
// the window will release its reference on the bin now, then it will release its reference on the dummy view when the window itself is finally released
|
||||
[w->window setContentView:[[NSView alloc] initWithFrame:NSZeroRect]];
|
||||
uiControlDestroy(w->bin);
|
||||
// now destroy the delegate
|
||||
[w->window setDelegate:nil];
|
||||
[w->delegate release];
|
||||
// now destroy ourselves
|
||||
// don't call the base; we use a different method
|
||||
[w->window close]; // see below about releasing when closed
|
||||
}
|
||||
|
||||
static uintptr_t windowHandle(uiControl *c)
|
||||
{
|
||||
struct window *w = (struct window *) c;
|
||||
|
||||
return (uintptr_t) (w->window);
|
||||
}
|
||||
|
||||
static void windowCommitShow(uiControl *c)
|
||||
{
|
||||
struct window *w = (struct window *) c;
|
||||
|
||||
[w->window makeKeyAndOrderFront:w->window];
|
||||
}
|
||||
|
||||
static void windowCommitHide(uiControl *c)
|
||||
{
|
||||
struct window *w = (struct window *) c;
|
||||
|
||||
[w->window orderOut:w->window];
|
||||
}
|
||||
|
||||
static void windowContainerUpdateState(uiControl *c)
|
||||
{
|
||||
struct window *w = (struct window *) c;
|
||||
|
||||
if (w->child != NULL)
|
||||
uiControlUpdateState(w->child);
|
||||
}
|
||||
|
||||
static char *windowTitle(uiWindow *ww)
|
||||
{
|
||||
struct window *w = (struct window *) ww;
|
||||
|
||||
return uiDarwinNSStringToText([w->window title]);
|
||||
}
|
||||
|
||||
static void windowSetTitle(uiWindow *ww, const char *title)
|
||||
{
|
||||
struct window *w = (struct window *) ww;
|
||||
|
||||
[w->window setTitle:toNSString(title)];
|
||||
}
|
||||
|
||||
static void windowOnClosing(uiWindow *ww, int (*f)(uiWindow *, void *), void *data)
|
||||
{
|
||||
struct window *w = (struct window *) ww;
|
||||
|
||||
[w->delegate setOnClosing:f data:data];
|
||||
}
|
||||
|
||||
static void windowSetChild(uiWindow *ww, uiControl *child)
|
||||
{
|
||||
struct window *w = (struct window *) ww;
|
||||
|
||||
w->child = child;
|
||||
binSetChild(w->bin, w->child);
|
||||
}
|
||||
|
||||
static int windowMargined(uiWindow *ww)
|
||||
{
|
||||
struct window *w = (struct window *) ww;
|
||||
|
||||
return binMargined(w->bin);
|
||||
}
|
||||
|
||||
static void windowSetMargined(uiWindow *ww, int margined)
|
||||
{
|
||||
struct window *w = (struct window *) ww;
|
||||
|
||||
binSetMargined(w->bin, margined);
|
||||
}
|
||||
|
||||
static void windowResizeChild(uiWindow *ww)
|
||||
{
|
||||
complain("uiWindowResizeChild() meaningless on OS X");
|
||||
}
|
||||
|
||||
uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar)
|
||||
{
|
||||
struct window *w;
|
||||
NSView *binView;
|
||||
|
||||
finalizeMenus();
|
||||
|
||||
w = (struct window *) uiNewControl(uiTypeWindow());
|
||||
|
||||
w->window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, (CGFloat) width, (CGFloat) height)
|
||||
styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:YES];
|
||||
[w->window setTitle:toNSString(title)];
|
||||
|
||||
// a NSWindow is not a NSView, but nothing we're doing in this function is view-specific
|
||||
uiDarwinMakeSingleViewControl(uiControl(w), (NSView *) (w->window), NO);
|
||||
|
||||
// explicitly release when closed
|
||||
// the only thing that closes the window is us anyway
|
||||
[w->window setReleasedWhenClosed:YES];
|
||||
|
||||
w->delegate = [windowDelegate new];
|
||||
[w->delegate setuiWindow:uiWindow(w)];
|
||||
[w->window setDelegate:w->delegate];
|
||||
|
||||
w->bin = newBin();
|
||||
binView = (NSView *) uiControlHandle(uiControl(w->bin));
|
||||
[w->window setContentView:binView];
|
||||
|
||||
[w->delegate setOnClosing:defaultOnClosing data:NULL];
|
||||
|
||||
uiControl(w)->Handle = windowHandle;
|
||||
uiControl(w)->CommitDestroy = windowCommitDestroy;
|
||||
uiControl(w)->CommitShow = windowCommitShow;
|
||||
uiControl(w)->CommitHide = windowCommitHide;
|
||||
uiControl(w)->ContainerUpdateState = windowContainerUpdateState;
|
||||
|
||||
uiWindow(w)->Title = windowTitle;
|
||||
uiWindow(w)->SetTitle = windowSetTitle;
|
||||
uiWindow(w)->OnClosing = windowOnClosing;
|
||||
uiWindow(w)->SetChild = windowSetChild;
|
||||
uiWindow(w)->Margined = windowMargined;
|
||||
uiWindow(w)->SetMargined = windowSetMargined;
|
||||
uiWindow(w)->ResizeChild = windowResizeChild;
|
||||
|
||||
return uiWindow(w);
|
||||
}
|
||||
|
||||
uiWindow *windowFromNSWindow(NSWindow *w)
|
||||
{
|
||||
windowDelegate *d;
|
||||
|
||||
if (w == nil)
|
||||
return NULL;
|
||||
d = (windowDelegate *) [w delegate];
|
||||
return [d getuiWindow];
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
// 7 april 2015
|
||||
|
||||
/*
|
||||
This file assumes that you have imported <Cocoa/Cocoa.h> and "ui.h" beforehand. It provides API-specific functions for interfacing with foreign controls on Mac OS X.
|
||||
*/
|
||||
|
||||
#ifndef __UI_UI_DARWIN_H__
|
||||
#define __UI_UI_DARWIN_H__
|
||||
|
||||
// TODO document
|
||||
_UI_EXTERN void uiDarwinMakeSingleViewControl(uiControl *, NSView *, BOOL);
|
||||
|
||||
// You can use this function from within your control implementations to return text strings that can be freed with uiFreeText().
|
||||
_UI_EXTERN char *uiDarwinNSStringToText(NSString *);
|
||||
|
||||
struct uiSizingSys {
|
||||
// this structure currently left blank
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue