Update to v094r09 release.

byuu says:

This will easily be the biggest diff in the history of higan. And not in
a good way.

* target-higan and target-loki have been blown away completely
* nall and ruby massively updated
* phoenix replaced with hiro (pretty near a total rewrite)
* target-higan restarted using hiro (just a window for now)
* all emulation cores updated to compile again
* installation changed to not require root privileges (installs locally)

For the foreseeable future (maybe even permanently?), the new higan UI
will only build under Linux/BSD with GTK+ 2.20+. Probably the most
likely route for Windows/OS X will be to try and figure out how to build
hiro/GTK on those platforms, as awful as that would be. The other
alternative would be to produce new UIs for those platforms ... which
would actually be a good opportunity to make something much more user
friendly.

Being that I just started on this a few hours ago, that means that for
at least a few weeks, don't expect to be able to actually play any
games. Right now, you can pretty much just compile the binary and that's
it. It's quite possible that some nall changes didn't produce
compilation errors, but will produce runtime errors. So until the UI can
actually load games, we won't know if anything is broken. But we should
mostly be okay. It was mostly just trim<1> -> trim changes, moving to
Hash::SHA256 (much cleaner), and patching some reckless memory copy
functions enough to compile.

Progress isn't going to be like it was before: I'm now dividing my time
much thinner between studying and other hobbies.

My aim this time is not to produce a binary for everyone to play games
on. Rather, it's to keep the emulator alive. I want to be able to apply
critical patches again. And I would also like the base of the emulator
to live on, for use in other emulator frontends that utilize higan.
This commit is contained in:
Tim Allen
2015-02-26 21:10:46 +11:00
parent 1a7bc6bb87
commit a512d14628
793 changed files with 20182 additions and 19416 deletions

View File

@@ -0,0 +1,80 @@
@implementation CocoaButton : NSButton
-(id) initWith:(phoenix::Button&)buttonReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
button = &buttonReference;
[self setTarget:self];
[self setAction:@selector(activate:)];
//NSRoundedBezelStyle has a fixed height; which breaks both icons and larger/smaller text
[self setBezelStyle:NSRegularSquareBezelStyle];
}
return self;
}
-(IBAction) activate:(id)sender {
if(button->onActivate) button->onActivate();
}
@end
namespace phoenix {
Size pButton::minimumSize() {
Size size = Font::size(button.font(), button.state.text);
if(button.state.orientation == Orientation::Horizontal) {
size.width += button.state.image.width;
size.height = max(button.state.image.height, size.height);
}
if(button.state.orientation == Orientation::Vertical) {
size.width = max(button.state.image.width, size.width);
size.height += button.state.image.height;
}
return {size.width + (button.state.text ? 20 : 4), size.height + 4};
}
void pButton::setBordered(bool bordered) {
}
void pButton::setGeometry(Geometry geometry) {
pWidget::setGeometry({
geometry.x - 2, geometry.y - 2,
geometry.width + 4, geometry.height + 4
});
}
void pButton::setImage(const image& image, Orientation orientation) {
@autoreleasepool {
if(image.empty()) {
[cocoaView setImage:nil];
return;
}
[cocoaView setImage:NSMakeImage(image)];
if(orientation == Orientation::Horizontal) [cocoaView setImagePosition:NSImageLeft];
if(orientation == Orientation::Vertical ) [cocoaView setImagePosition:NSImageAbove];
}
}
void pButton::setText(string text) {
@autoreleasepool {
[cocoaView setTitle:[NSString stringWithUTF8String:text]];
}
}
void pButton::constructor() {
@autoreleasepool {
cocoaView = cocoaButton = [[CocoaButton alloc] initWith:button];
}
}
void pButton::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,26 @@
@interface CocoaButton : NSButton {
@public
phoenix::Button* button;
}
-(id) initWith:(phoenix::Button&)button;
-(IBAction) activate:(id)sender;
@end
namespace phoenix {
struct pButton : public pWidget {
Button& button;
CocoaButton* cocoaButton = nullptr;
Size minimumSize();
void setBordered(bool bordered);
void setGeometry(Geometry geometry);
void setImage(const image& image, Orientation orientation);
void setText(string text);
pButton(Button& button) : pWidget(button), button(button) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,214 @@
@implementation CocoaCanvas : NSImageView
-(id) initWith:(phoenix::Canvas&)canvasReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
canvas = &canvasReference;
[self setEditable:NO]; //disable image drag-and-drop functionality
NSTrackingArea* area = [[[NSTrackingArea alloc] initWithRect:[self frame]
options:NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow | NSTrackingInVisibleRect
owner:self userInfo:nil
] autorelease];
[self addTrackingArea:area];
}
return self;
}
-(NSDragOperation) draggingEntered:(id<NSDraggingInfo>)sender {
return DropPathsOperation(sender);
}
-(BOOL) performDragOperation:(id<NSDraggingInfo>)sender {
lstring paths = DropPaths(sender);
if(paths.empty()) return NO;
if(canvas->onDrop) canvas->onDrop(paths);
return YES;
}
-(void) mouseButton:(NSEvent*)event down:(BOOL)isDown {
if(auto& callback = isDown ? canvas->onMousePress : canvas->onMouseRelease) {
switch([event buttonNumber]) {
case 0: return callback(phoenix::Mouse::Button::Left);
case 1: return callback(phoenix::Mouse::Button::Right);
case 2: return callback(phoenix::Mouse::Button::Middle);
}
}
}
-(void) mouseExited:(NSEvent*)event {
if(canvas->onMouseLeave) canvas->onMouseLeave();
}
-(void) mouseMove:(NSEvent*)event {
if([event window] == nil) return;
NSPoint location = [self convertPoint:[event locationInWindow] fromView:nil];
if(canvas->onMouseMove) canvas->onMouseMove({location.x, [self frame].size.height - 1 - location.y});
}
-(void) mouseDown:(NSEvent*)event {
[self mouseButton:event down:YES];
}
-(void) mouseUp:(NSEvent*)event {
[self mouseButton:event down:NO];
}
-(void) mouseDragged:(NSEvent*)event {
[self mouseMove:event];
}
-(void) rightMouseDown:(NSEvent*)event {
[self mouseButton:event down:YES];
}
-(void) rightMouseUp:(NSEvent*)event {
[self mouseButton:event down:NO];
}
-(void) rightMouseDragged:(NSEvent*)event {
[self mouseMove:event];
}
-(void) otherMouseDown:(NSEvent*)event {
[self mouseButton:event down:YES];
}
-(void) otherMouseUp:(NSEvent*)event {
[self mouseButton:event down:NO];
}
-(void) otherMouseDragged:(NSEvent*)event {
[self mouseMove:event];
}
@end
namespace phoenix {
void pCanvas::setDroppable(bool droppable) {
@autoreleasepool {
if(droppable) {
[cocoaCanvas registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
} else {
[cocoaCanvas unregisterDraggedTypes];
}
}
}
void pCanvas::setGeometry(Geometry geometry) {
if(canvas.state.width == 0 || canvas.state.height == 0) rasterize();
unsigned width = canvas.state.width;
unsigned height = canvas.state.height;
if(width == 0) width = widget.state.geometry.width;
if(height == 0) height = widget.state.geometry.height;
if(width < geometry.width) {
geometry.x += (geometry.width - width) / 2;
geometry.width = width;
}
if(height < geometry.height) {
geometry.y += (geometry.height - height) / 2;
geometry.height = height;
}
pWidget::setGeometry(geometry);
}
void pCanvas::setMode(Canvas::Mode mode) {
rasterize(), redraw();
}
void pCanvas::setSize(Size size) {
rasterize(), redraw();
}
void pCanvas::constructor() {
@autoreleasepool {
cocoaView = cocoaCanvas = [[CocoaCanvas alloc] initWith:canvas];
}
setSize(canvas.size());
}
void pCanvas::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
void pCanvas::rasterize() {
@autoreleasepool {
unsigned width = canvas.state.width;
unsigned height = canvas.state.height;
if(width == 0) width = widget.state.geometry.width;
if(height == 0) height = widget.state.geometry.height;
if(width != surfaceWidth || height != surfaceHeight) {
NSImage* image = [[[NSImage alloc] initWithSize:NSMakeSize(width, height)] autorelease];
NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:nil
pixelsWide:width pixelsHigh:height
bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES
isPlanar:NO colorSpaceName:NSCalibratedRGBColorSpace
bitmapFormat:NSAlphaNonpremultipliedBitmapFormat
bytesPerRow:width * 4 bitsPerPixel:32
] autorelease];
[image addRepresentation:bitmap];
[cocoaView setImage:image];
surfaceWidth = width;
surfaceHeight = height;
}
if(NSBitmapImageRep* bitmap = [[[cocoaView image] representations] objectAtIndex:0]) {
uint32_t* target = (uint32_t*)[bitmap bitmapData];
if(canvas.state.mode == Canvas::Mode::Color) {
nall::image image;
image.allocate(width, height);
image.fill(canvas.state.color.argb());
memcpy(target, image.data, image.size);
}
if(canvas.state.mode == Canvas::Mode::Gradient) {
nall::image image;
image.allocate(width, height);
image.gradient(
canvas.state.gradient[0].argb(), canvas.state.gradient[1].argb(), canvas.state.gradient[2].argb(), canvas.state.gradient[3].argb()
);
memcpy(target, image.data, image.size);
}
if(canvas.state.mode == Canvas::Mode::Image) {
nall::image image = canvas.state.image;
image.scale(width, height);
image.transform(0, 32, 255u << 24, 255u << 16, 255u << 8, 255u << 0);
memcpy(target, image.data, image.size);
}
if(canvas.state.mode == Canvas::Mode::Data) {
if(width == canvas.state.width && height == canvas.state.height) {
memcpy(target, canvas.state.data, width * height * sizeof(uint32_t));
} else {
memset(target, 0x00, width * height * sizeof(uint32_t));
}
}
//ARGB -> ABGR transformation
for(unsigned n = 0; n < width * height; n++) {
uint32_t color = *target;
color = (color & 0xff00ff00) | ((color & 0xff0000) >> 16) | ((color & 0x0000ff) << 16);
*target++ = color;
}
}
}
}
void pCanvas::redraw() {
@autoreleasepool {
[cocoaView setNeedsDisplay:YES];
}
}
}

View File

@@ -0,0 +1,42 @@
@interface CocoaCanvas : NSImageView {
@public
phoenix::Canvas* canvas;
}
-(id) initWith:(phoenix::Canvas&)canvas;
-(NSDragOperation) draggingEntered:(id<NSDraggingInfo>)sender;
-(BOOL) performDragOperation:(id<NSDraggingInfo>)sender;
-(void) mouseButton:(NSEvent*)event down:(BOOL)isDown;
-(void) mouseExited:(NSEvent*)event;
-(void) mouseMove:(NSEvent*)event;
-(void) mouseDown:(NSEvent*)event;
-(void) mouseUp:(NSEvent*)event;
-(void) mouseDragged:(NSEvent*)event;
-(void) rightMouseDown:(NSEvent*)event;
-(void) rightMouseUp:(NSEvent*)event;
-(void) rightMouseDragged:(NSEvent*)event;
-(void) otherMouseDown:(NSEvent*)event;
-(void) otherMouseUp:(NSEvent*)event;
-(void) otherMouseDragged:(NSEvent*)event;
@end
namespace phoenix {
struct pCanvas : public pWidget {
Canvas& canvas;
CocoaCanvas* cocoaCanvas = nullptr;
unsigned surfaceWidth = 0;
unsigned surfaceHeight = 0;
void setDroppable(bool droppable);
void setGeometry(Geometry geometry);
void setMode(Canvas::Mode mode);
void setSize(Size size);
pCanvas(Canvas& canvas) : pWidget(canvas), canvas(canvas) {}
void constructor();
void destructor();
void rasterize();
void redraw();
};
}

View File

@@ -0,0 +1,85 @@
@implementation CocoaCheckButton : NSButton
-(id) initWith:(phoenix::CheckButton&)checkButtonReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
checkButton = &checkButtonReference;
[self setTarget:self];
[self setAction:@selector(activate:)];
[self setBezelStyle:NSRegularSquareBezelStyle];
[self setButtonType:NSOnOffButton];
}
return self;
}
-(IBAction) activate:(id)sender {
checkButton->state.checked = [self state] != NSOffState;
if(checkButton->onToggle) checkButton->onToggle();
}
@end
namespace phoenix {
Size pCheckButton::minimumSize() {
Size size = Font::size(checkButton.font(), checkButton.state.text);
if(checkButton.state.orientation == Orientation::Horizontal) {
size.width += checkButton.state.image.width;
size.height = max(checkButton.state.image.height, size.height);
}
if(checkButton.state.orientation == Orientation::Vertical) {
size.width = max(checkButton.state.image.width, size.width);
size.height += checkButton.state.image.height;
}
return {size.width + 20, size.height + 4};
}
void pCheckButton::setChecked(bool checked) {
@autoreleasepool {
[cocoaView setState:checked ? NSOnState : NSOffState];
}
}
void pCheckButton::setGeometry(Geometry geometry) {
pWidget::setGeometry({
geometry.x - 2, geometry.y - 2,
geometry.width + 4, geometry.height + 4
});
}
void pCheckButton::setImage(const image& image, Orientation orientation) {
@autoreleasepool {
if(image.empty()) {
[cocoaView setImage:nil];
return;
}
[cocoaView setImage:NSMakeImage(image)];
if(orientation == Orientation::Horizontal) [cocoaView setImagePosition:NSImageLeft];
if(orientation == Orientation::Vertical ) [cocoaView setImagePosition:NSImageAbove];
}
}
void pCheckButton::setText(string text) {
@autoreleasepool {
[cocoaView setTitle:[NSString stringWithUTF8String:text]];
}
}
void pCheckButton::constructor() {
@autoreleasepool {
cocoaView = cocoaCheckButton = [[CocoaCheckButton alloc] initWith:checkButton];
}
}
void pCheckButton::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,26 @@
@interface CocoaCheckButton : NSButton {
@public
phoenix::CheckButton* checkButton;
}
-(id) initWith:(phoenix::CheckButton&)checkButton;
-(IBAction) activate:(id)sender;
@end
namespace phoenix {
struct pCheckButton : public pWidget {
CheckButton& checkButton;
CocoaCheckButton* cocoaCheckButton = nullptr;
Size minimumSize();
void setChecked(bool checked);
void setGeometry(Geometry geometry);
void setImage(const image& image, Orientation orientation);
void setText(string text);
pCheckButton(CheckButton& checkButton) : pWidget(checkButton), checkButton(checkButton) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,61 @@
@implementation CocoaCheckLabel : NSButton
-(id) initWith:(phoenix::CheckLabel&)checkLabelReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
checkLabel = &checkLabelReference;
[self setTarget:self];
[self setAction:@selector(activate:)];
[self setButtonType:NSSwitchButton];
}
return self;
}
-(IBAction) activate:(id)sender {
checkLabel->state.checked = [self state] != NSOffState;
if(checkLabel->onToggle) checkLabel->onToggle();
}
@end
namespace phoenix {
Size pCheckLabel::minimumSize() {
Size size = Font::size(checkLabel.font(), checkLabel.state.text);
return {size.width + 20, size.height};
}
void pCheckLabel::setChecked(bool checked) {
@autoreleasepool {
[cocoaView setState:checked ? NSOnState : NSOffState];
}
}
void pCheckLabel::setGeometry(Geometry geometry) {
pWidget::setGeometry({
geometry.x - 2, geometry.y,
geometry.width + 4, geometry.height
});
}
void pCheckLabel::setText(string text) {
@autoreleasepool {
[cocoaView setTitle:[NSString stringWithUTF8String:text]];
}
}
void pCheckLabel::constructor() {
@autoreleasepool {
cocoaView = cocoaCheckLabel = [[CocoaCheckLabel alloc] initWith:checkLabel];
setChecked(checkLabel.state.checked);
setText(checkLabel.state.text);
}
}
void pCheckLabel::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,25 @@
@interface CocoaCheckLabel : NSButton {
@public
phoenix::CheckLabel* checkLabel;
}
-(id) initWith:(phoenix::CheckLabel&)checkLabel;
-(IBAction) activate:(id)sender;
@end
namespace phoenix {
struct pCheckLabel : public pWidget {
CheckLabel& checkLabel;
CocoaCheckLabel* cocoaCheckLabel = nullptr;
Size minimumSize();
void setChecked(bool checked);
void setGeometry(Geometry geometry);
void setText(string text);
pCheckLabel(CheckLabel& checkLabel) : pWidget(checkLabel), checkLabel(checkLabel) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,78 @@
@implementation CocoaComboButton : NSPopUpButton
-(id) initWith:(phoenix::ComboButton&)comboButtonReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0) pullsDown:NO]) {
comboButton = &comboButtonReference;
[self setTarget:self];
[self setAction:@selector(activate:)];
}
return self;
}
-(IBAction) activate:(id)sender {
comboButton->state.selection = [self indexOfSelectedItem];
if(comboButton->onChange) comboButton->onChange();
}
@end
namespace phoenix {
void pComboButton::append(string text) {
@autoreleasepool {
[cocoaView addItemWithTitle:[NSString stringWithUTF8String:text]];
}
}
Size pComboButton::minimumSize() {
unsigned maximumWidth = 0;
for(auto& text : comboButton.state.text) maximumWidth = max(maximumWidth, Font::size(comboButton.font(), text).width);
Size size = Font::size(comboButton.font(), " ");
return {maximumWidth + 36, size.height + 6};
}
void pComboButton::remove(unsigned selection) {
@autoreleasepool {
[cocoaView removeItemAtIndex:selection];
}
}
void pComboButton::reset() {
@autoreleasepool {
[cocoaView removeAllItems];
}
}
void pComboButton::setGeometry(Geometry geometry) {
pWidget::setGeometry({
geometry.x - 2, geometry.y,
geometry.width + 4, geometry.height
});
}
void pComboButton::setSelection(unsigned selection) {
@autoreleasepool {
[cocoaView selectItemAtIndex:selection];
}
}
void pComboButton::setText(unsigned selection, string text) {
@autoreleasepool {
[[cocoaView itemAtIndex:selection] setTitle:[NSString stringWithUTF8String:text]];
}
}
void pComboButton::constructor() {
@autoreleasepool {
cocoaView = cocoaComboButton = [[CocoaComboButton alloc] initWith:comboButton];
}
}
void pComboButton::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,28 @@
@interface CocoaComboButton : NSPopUpButton {
@public
phoenix::ComboButton* comboButton;
}
-(id) initWith:(phoenix::ComboButton&)comboButton;
-(IBAction) activate:(id)sender;
@end
namespace phoenix {
struct pComboButton : public pWidget {
ComboButton& comboButton;
CocoaComboButton* cocoaComboButton = nullptr;
void append(string text);
Size minimumSize();
void remove(unsigned selection);
void reset();
void setGeometry(Geometry geometry);
void setSelection(unsigned selection);
void setText(unsigned selection, string text);
pComboButton(ComboButton& comboButton) : pWidget(comboButton), comboButton(comboButton) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,41 @@
@implementation CocoaConsole : NSScrollView
-(id) initWith:(phoenix::Console&)consoleReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
console = &consoleReference;
}
return self;
}
@end
namespace phoenix {
void pConsole::print(string text) {
}
void pConsole::reset() {
}
void pConsole::setBackgroundColor(Color color) {
}
void pConsole::setForegroundColor(Color color) {
}
void pConsole::setPrompt(string prompt) {
}
void pConsole::constructor() {
@autoreleasepool {
cocoaView = cocoaConsole = [[CocoaConsole alloc] initWith:console];
}
}
void pConsole::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,25 @@
@interface CocoaConsole : NSScrollView {
@public
phoenix::Console* console;
}
-(id) initWith:(phoenix::Console&)console;
@end
namespace phoenix {
struct pConsole : public pWidget {
Console& console;
CocoaConsole* cocoaConsole = nullptr;
void print(string text);
void reset();
void setBackgroundColor(Color color);
void setForegroundColor(Color color);
void setPrompt(string prompt);
pConsole(Console& console) : pWidget(console), console(console) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,68 @@
@implementation CocoaFrame : NSBox
-(id) initWith:(phoenix::Frame&)frameReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
frame = &frameReference;
[self setTitle:@""];
}
return self;
}
@end
namespace phoenix {
void pFrame::setEnabled(bool enabled) {
if(frame.state.layout) frame.state.layout->setEnabled(frame.state.layout->enabled());
pWidget::setEnabled(enabled);
}
void pFrame::setFont(string font) {
@autoreleasepool {
[cocoaView setTitleFont:pFont::cocoaFont(font)];
}
}
void pFrame::setGeometry(Geometry geometry) {
bool empty = frame.state.text.empty();
Size size = Font::size(frame.font(), frame.state.text);
pWidget::setGeometry({
geometry.x - 3, geometry.y - (empty ? size.height - 2 : 1),
geometry.width + 6, geometry.height + (empty ? size.height + 2 : 5)
});
if(frame.state.layout == nullptr) return;
geometry.x += 1, geometry.y += (empty ? 1 : size.height - 2);
geometry.width -= 2, geometry.height -= (empty ? 1 : size.height - 1);
frame.state.layout->setGeometry(geometry);
}
void pFrame::setText(string text) {
@autoreleasepool {
[cocoaView setTitle:[NSString stringWithUTF8String:text]];
}
}
void pFrame::setVisible(bool visible) {
if(frame.state.layout) frame.state.layout->setVisible(frame.state.layout->visible());
pWidget::setVisible(visible);
}
void pFrame::constructor() {
@autoreleasepool {
cocoaView = cocoaFrame = [[CocoaFrame alloc] initWith:frame];
}
}
void pFrame::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
void pFrame::orphan() {
destructor();
constructor();
}
}

View File

@@ -0,0 +1,26 @@
@interface CocoaFrame : NSBox {
@public
phoenix::Frame* frame;
}
-(id) initWith:(phoenix::Frame&)frame;
@end
namespace phoenix {
struct pFrame : public pWidget {
Frame& frame;
CocoaFrame* cocoaFrame = nullptr;
void setEnabled(bool enabled);
void setFont(string font);
void setGeometry(Geometry geometry);
void setText(string text);
void setVisible(bool visible);
pFrame(Frame& frame) : pWidget(frame), frame(frame) {}
void constructor();
void destructor();
void orphan();
};
}

View File

@@ -0,0 +1,47 @@
@implementation CocoaHexEdit : NSScrollView
-(id) initWith:(phoenix::HexEdit&)hexEditReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
hexEdit = &hexEditReference;
}
return self;
}
@end
namespace phoenix {
void pHexEdit::setBackgroundColor(Color color) {
}
void pHexEdit::setColumns(unsigned columns) {
}
void pHexEdit::setForegroundColor(Color color) {
}
void pHexEdit::setLength(unsigned length) {
}
void pHexEdit::setOffset(unsigned offset) {
}
void pHexEdit::setRows(unsigned rows) {
}
void pHexEdit::update() {
}
void pHexEdit::constructor() {
@autoreleasepool {
cocoaView = cocoaHexEdit = [[CocoaHexEdit alloc] initWith:hexEdit];
}
}
void pHexEdit::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,27 @@
@interface CocoaHexEdit : NSScrollView {
@public
phoenix::HexEdit* hexEdit;
}
-(id) initWith:(phoenix::HexEdit&)hexEdit;
@end
namespace phoenix {
struct pHexEdit : public pWidget {
HexEdit& hexEdit;
CocoaHexEdit* cocoaHexEdit = nullptr;
void setBackgroundColor(Color color);
void setColumns(unsigned columns);
void setForegroundColor(Color color);
void setLength(unsigned length);
void setOffset(unsigned offset);
void setRows(unsigned rows);
void update();
pHexEdit(HexEdit& hexEdit) : pWidget(hexEdit), hexEdit(hexEdit) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,85 @@
@implementation CocoaHorizontalScroller : NSScroller
-(id) initWith:(phoenix::HorizontalScroller&)horizontalScrollerReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 1, 0)]) {
horizontalScroller = &horizontalScrollerReference;
[self setTarget:self];
[self setAction:@selector(scroll:)];
[self setControlSize:NSRegularControlSize];
[self setScrollerStyle:NSScrollerStyleLegacy];
[self setEnabled:YES];
[self update];
}
return self;
}
-(void) update {
double d = 1.0 / horizontalScroller->state.length;
double f = d * horizontalScroller->state.position;
[self setDoubleValue:f];
[self setKnobProportion:d];
}
-(IBAction) scroll:(id)sender {
auto& state = horizontalScroller->state;
switch([self hitPart]) {
case NSScrollerIncrementLine:
case NSScrollerIncrementPage:
if(state.position < state.length - 1) state.position++;
[self update];
break;
case NSScrollerDecrementLine:
case NSScrollerDecrementPage:
if(state.position) state.position--;
[self update];
break;
case NSScrollerKnob:
state.position = [self doubleValue] * state.length;
break;
}
if(horizontalScroller->onChange) horizontalScroller->onChange();
}
@end
namespace phoenix {
Size pHorizontalScroller::minimumSize() {
@autoreleasepool {
return {32, [NSScroller scrollerWidthForControlSize:NSRegularControlSize scrollerStyle:NSScrollerStyleLegacy]};
}
}
void pHorizontalScroller::setLength(unsigned length) {
@autoreleasepool {
[cocoaView update];
}
}
void pHorizontalScroller::setPosition(unsigned position) {
@autoreleasepool {
[cocoaView update];
}
}
void pHorizontalScroller::constructor() {
@autoreleasepool {
cocoaView = cocoaHorizontalScroller = [[CocoaHorizontalScroller alloc] initWith:horizontalScroller];
}
}
void pHorizontalScroller::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,25 @@
@interface CocoaHorizontalScroller : NSScroller {
@public
phoenix::HorizontalScroller* horizontalScroller;
}
-(id) initWith:(phoenix::HorizontalScroller&)horizontalScroller;
-(void) update;
-(IBAction) scroll:(id)sender;
@end
namespace phoenix {
struct pHorizontalScroller : public pWidget {
HorizontalScroller& horizontalScroller;
CocoaHorizontalScroller* cocoaHorizontalScroller = nullptr;
Size minimumSize();
void setLength(unsigned length);
void setPosition(unsigned position);
pHorizontalScroller(HorizontalScroller& horizontalScroller) : pWidget(horizontalScroller), horizontalScroller(horizontalScroller) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,61 @@
@implementation CocoaHorizontalSlider : NSSlider
-(id) initWith:(phoenix::HorizontalSlider&)horizontalSliderReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 1, 0)]) {
horizontalSlider = &horizontalSliderReference;
[self setTarget:self];
[self setAction:@selector(activate:)];
[self setMinValue:0];
}
return self;
}
-(IBAction) activate:(id)sender {
horizontalSlider->state.position = [self doubleValue];
if(horizontalSlider->onChange) horizontalSlider->onChange();
}
@end
namespace phoenix {
Size pHorizontalSlider::minimumSize() {
return {48, 20};
}
void pHorizontalSlider::setGeometry(Geometry geometry) {
pWidget::setGeometry({
geometry.x - 2, geometry.y,
geometry.width + 4, geometry.height
});
}
void pHorizontalSlider::setLength(unsigned length) {
@autoreleasepool {
[cocoaView setMaxValue:length];
}
}
void pHorizontalSlider::setPosition(unsigned position) {
@autoreleasepool {
[cocoaView setDoubleValue:position];
}
}
void pHorizontalSlider::constructor() {
@autoreleasepool {
cocoaView = cocoaHorizontalSlider = [[CocoaHorizontalSlider alloc] initWith:horizontalSlider];
setLength(horizontalSlider.state.length);
setPosition(horizontalSlider.state.position);
}
}
void pHorizontalSlider::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,25 @@
@interface CocoaHorizontalSlider : NSSlider {
@public
phoenix::HorizontalSlider* horizontalSlider;
}
-(id) initWith:(phoenix::HorizontalSlider&)horizontalSlider;
-(IBAction) activate:(id)sender;
@end
namespace phoenix {
struct pHorizontalSlider : public pWidget {
HorizontalSlider& horizontalSlider;
CocoaHorizontalSlider* cocoaHorizontalSlider = nullptr;
Size minimumSize();
void setGeometry(Geometry geometry);
void setLength(unsigned length);
void setPosition(unsigned position);
pHorizontalSlider(HorizontalSlider& horizontalSlider) : pWidget(horizontalSlider), horizontalSlider(horizontalSlider) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,62 @@
@implementation CocoaLabel : NSTextField
-(id) initWith:(phoenix::Label&)labelReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
label = &labelReference;
[self setAlignment:NSLeftTextAlignment];
[self setBordered:NO];
[self setDrawsBackground:NO];
[self setEditable:NO];
}
return self;
}
@end
namespace phoenix {
Size pLabel::minimumSize() {
Size size = Font::size(label.font(), label.state.text);
return {size.width, size.height};
}
void pLabel::setGeometry(Geometry geometry) {
//NSTextField does not support vertical text centering:
//simulate this by adjusting the geometry placement (reduce height, move view down)
unsigned height = Font::size(label.font(), " ").height;
unsigned widgetHeight = geometry.height + 4; //+4 compensates for margin adjust
auto offset = geometry;
if(widgetHeight > height) {
unsigned diff = widgetHeight - height;
offset.y += diff >> 1;
offset.height -= diff >> 1;
}
pWidget::setGeometry({
offset.x - 3, offset.y - 3,
offset.width + 6, offset.height + 6
});
}
void pLabel::setText(string text) {
@autoreleasepool {
[cocoaView setStringValue:[NSString stringWithUTF8String:text]];
}
}
void pLabel::constructor() {
@autoreleasepool {
cocoaView = cocoaLabel = [[CocoaLabel alloc] initWith:label];
setText(label.state.text);
}
}
void pLabel::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,23 @@
@interface CocoaLabel : NSTextField {
@public
phoenix::Label* label;
}
-(id) initWith:(phoenix::Label&)label;
@end
namespace phoenix {
struct pLabel : public pWidget {
Label& label;
CocoaLabel* cocoaLabel = nullptr;
Size minimumSize();
void setGeometry(Geometry geometry);
void setText(string text);
pLabel(Label& label) : pWidget(label), label(label) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,9 @@
namespace phoenix {
struct pLayout : public pSizable {
Layout& layout;
pLayout(Layout& layout) : pSizable(layout), layout(layout) {}
};
}

View File

@@ -0,0 +1,71 @@
@implementation CocoaLineEdit : NSTextField
-(id) initWith:(phoenix::LineEdit&)lineEditReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
lineEdit = &lineEditReference;
[self setDelegate:self];
[self setTarget:self];
[self setAction:@selector(activate:)];
//prevent focus changes from generating activate event
[[self cell] setSendsActionOnEndEditing:NO];
}
return self;
}
-(void) textDidChange:(NSNotification*)n {
if(lineEdit->onChange) lineEdit->onChange();
}
-(IBAction) activate:(id)sender {
if(lineEdit->onActivate) lineEdit->onActivate();
}
@end
namespace phoenix {
Size pLineEdit::minimumSize() {
Size size = Font::size(lineEdit.font(), lineEdit.state.text);
return {size.width + 10, size.height + 8};
}
void pLineEdit::setBackgroundColor(Color color) {
}
void pLineEdit::setEditable(bool editable) {
@autoreleasepool {
[cocoaView setEditable:editable];
}
}
void pLineEdit::setForegroundColor(Color color) {
}
void pLineEdit::setText(string text) {
@autoreleasepool {
[cocoaView setStringValue:[NSString stringWithUTF8String:text]];
}
}
string pLineEdit::text() {
@autoreleasepool {
return [[cocoaView stringValue] UTF8String];
}
}
void pLineEdit::constructor() {
@autoreleasepool {
cocoaView = cocoaLineEdit = [[CocoaLineEdit alloc] initWith:lineEdit];
setEditable(lineEdit.state.editable);
}
}
void pLineEdit::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,28 @@
@interface CocoaLineEdit : NSTextField <NSTextFieldDelegate> {
@public
phoenix::LineEdit* lineEdit;
}
-(id) initWith:(phoenix::LineEdit&)lineEdit;
-(void) textDidChange:(NSNotification*)n;
-(IBAction) activate:(id)sender;
@end
namespace phoenix {
struct pLineEdit : public pWidget {
LineEdit& lineEdit;
CocoaLineEdit* cocoaLineEdit = nullptr;
Size minimumSize();
void setBackgroundColor(Color color);
void setEditable(bool editable);
void setForegroundColor(Color color);
void setText(string text);
string text();
pLineEdit(LineEdit& lineEdit) : pWidget(lineEdit), lineEdit(lineEdit) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,333 @@
@implementation CocoaListView : NSScrollView
-(id) initWith:(phoenix::ListView&)listViewReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
listView = &listViewReference;
content = [[CocoaListViewContent alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)];
[self setDocumentView:content];
[self setBorderType:NSBezelBorder];
[self setHasVerticalScroller:YES];
[content setDataSource:self];
[content setDelegate:self];
[content setTarget:self];
[content setDoubleAction:@selector(doubleAction:)];
[content setAllowsColumnReordering:NO];
[content setAllowsColumnResizing:YES];
[content setAllowsColumnSelection:NO];
[content setAllowsEmptySelection:YES];
[content setAllowsMultipleSelection:NO];
[content setColumnAutoresizingStyle:NSTableViewLastColumnOnlyAutoresizingStyle];
font = nil;
[self setFont:nil];
}
return self;
}
-(void) dealloc {
[content release];
[font release];
[super dealloc];
}
-(CocoaListViewContent*) content {
return content;
}
-(NSFont*) font {
return font;
}
-(void) setFont:(NSFont*)fontPointer {
if(!fontPointer) fontPointer = [NSFont systemFontOfSize:12];
[fontPointer retain];
if(font) [font release];
font = fontPointer;
unsigned fontHeight = phoenix::pFont::size(font, " ").height;
[content setFont:font];
[content setRowHeight:fontHeight];
[self reloadColumns];
}
-(void) reloadColumns {
while([[content tableColumns] count]) {
[content removeTableColumn:[[content tableColumns] lastObject]];
}
if(listView->state.checkable) {
NSTableColumn *tableColumn = [[NSTableColumn alloc] initWithIdentifier:@"check"];
NSTableHeaderCell *headerCell = [[NSTableHeaderCell alloc] initTextCell:@""];
NSButtonCell *dataCell = [[NSButtonCell alloc] initTextCell:@""];
[dataCell setButtonType:NSSwitchButton];
[dataCell setControlSize:NSSmallControlSize];
[dataCell setRefusesFirstResponder:YES];
[tableColumn setResizingMask:NSTableColumnNoResizing];
[tableColumn setHeaderCell:headerCell];
[tableColumn setDataCell:dataCell];
[tableColumn setWidth:20.0];
[content addTableColumn:tableColumn];
}
lstring headers = listView->state.headerText;
if(headers.size() == 0) headers.append("");
[content setUsesAlternatingRowBackgroundColors:headers.size() >= 2];
for(unsigned column = 0; column < headers.size(); column++) {
NSTableColumn* tableColumn = [[NSTableColumn alloc] initWithIdentifier:[[NSNumber numberWithInteger:column] stringValue]];
NSTableHeaderCell* headerCell = [[NSTableHeaderCell alloc] initTextCell:[NSString stringWithUTF8String:headers(column)]];
CocoaListViewCell* dataCell = [[CocoaListViewCell alloc] initTextCell:@""];
[dataCell setEditable:NO];
[tableColumn setResizingMask:NSTableColumnAutoresizingMask | NSTableColumnUserResizingMask];
[tableColumn setHeaderCell:headerCell];
[tableColumn setDataCell:dataCell];
[content addTableColumn:tableColumn];
}
}
-(NSInteger) numberOfRowsInTableView:(NSTableView*)table {
return listView->state.text.size();
}
-(id) tableView:(NSTableView*)table objectValueForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row {
if([[tableColumn identifier] isEqualToString:@"check"]) {
auto checked = listView->state.checked(row) ? NSOnState : NSOffState;
return [NSNumber numberWithInteger:checked];
}
NSInteger column = [[tableColumn identifier] integerValue];
unsigned height = [table rowHeight];
NSString* text = [NSString stringWithUTF8String:listView->state.text(row)(column)];
NSImage* image = NSMakeImage(listView->state.image(row)(column), height, height);
if(image) return @{ @"text":text, @"image":image };
return @{ @"text":text };
}
-(BOOL) tableView:(NSTableView*)table shouldShowCellExpansionForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row {
return NO;
}
-(NSString*) tableView:(NSTableView*)table toolTipForCell:(NSCell*)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row mouseLocation:(NSPoint)mouseLocation {
return nil;
}
-(void) tableView:(NSTableView*)table setObjectValue:(id)object forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row {
if([[tableColumn identifier] isEqualToString:@"check"]) {
listView->state.checked(row) = [object integerValue] != NSOffState;
if(listView->onToggle) listView->onToggle(row);
}
}
-(void) tableView:(NSTableView*)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row {
[cell setFont:[self font]];
}
-(void) tableViewSelectionDidChange:(NSNotification*)notification {
listView->state.selected = true;
listView->state.selection = [content selectedRow];
if(listView->onChange) listView->onChange();
}
-(IBAction) activate:(id)sender {
if(listView->onActivate) listView->onActivate();
}
-(IBAction) doubleAction:(id)sender {
if([content clickedRow] >= 0) {
[self activate:self];
}
}
@end
@implementation CocoaListViewContent : NSTableView
-(void) keyDown:(NSEvent*)event {
auto character = [[event characters] characterAtIndex:0];
if(character == NSEnterCharacter || character == NSCarriageReturnCharacter) {
if([self selectedRow] >= 0) {
[[self delegate] activate:self];
return;
}
}
[super keyDown:event];
}
@end
@implementation CocoaListViewCell : NSTextFieldCell
//used by type-ahead
-(NSString*) stringValue {
return [[self objectValue] objectForKey:@"text"];
}
-(void) drawWithFrame:(NSRect)frame inView:(NSView*)view {
NSString* text = [[self objectValue] objectForKey:@"text"];
NSImage* image = [[self objectValue] objectForKey:@"image"];
unsigned textDisplacement = 0;
if(image) {
[[NSGraphicsContext currentContext] saveGraphicsState];
NSRect targetRect = NSMakeRect(frame.origin.x, frame.origin.y, frame.size.height, frame.size.height);
NSRect sourceRect = NSMakeRect(0, 0, [image size].width, [image size].height);
[image drawInRect:targetRect fromRect:sourceRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil];
[[NSGraphicsContext currentContext] restoreGraphicsState];
textDisplacement = frame.size.height + 2;
}
NSRect textRect = NSMakeRect(
frame.origin.x + textDisplacement, frame.origin.y,
frame.size.width - textDisplacement, frame.size.height
);
NSColor* textColor = [self isHighlighted]
? [NSColor alternateSelectedControlTextColor]
: [NSColor textColor];
[text drawInRect:textRect withAttributes:@{
NSForegroundColorAttributeName:textColor,
NSFontAttributeName:[self font]
}];
}
@end
namespace phoenix {
void pListView::append(const lstring& text) {
@autoreleasepool {
[[cocoaView content] reloadData];
}
}
void pListView::autoSizeColumns() {
@autoreleasepool {
if(listView.state.checkable) {
NSTableColumn* tableColumn = [[cocoaView content] tableColumnWithIdentifier:@"check"];
[tableColumn setWidth:20.0];
}
unsigned height = [[cocoaView content] rowHeight];
for(unsigned column = 0; column < max(1u, listView.state.headerText.size()); column++) {
NSTableColumn* tableColumn = [[cocoaView content] tableColumnWithIdentifier:[[NSNumber numberWithInteger:column] stringValue]];
unsigned minimumWidth = pFont::size([[tableColumn headerCell] font], listView.state.headerText(column)).width + 4;
for(unsigned row = 0; row < listView.state.text.size(); row++) {
unsigned width = pFont::size([cocoaView font], listView.state.text(row)(column)).width + 2;
if(listView.state.image(row)(height).empty() == false) width += height + 2;
if(width > minimumWidth) minimumWidth = width;
}
[tableColumn setWidth:minimumWidth];
}
[[cocoaView content] sizeLastColumnToFit];
}
}
void pListView::remove(unsigned selection) {
@autoreleasepool {
[[cocoaView content] reloadData];
}
}
void pListView::reset() {
@autoreleasepool {
[[cocoaView content] reloadData];
}
}
void pListView::setBackgroundColor(Color color) {
}
void pListView::setCheckable(bool checkable) {
@autoreleasepool {
[cocoaView reloadColumns];
}
}
void pListView::setChecked(unsigned selection, bool checked) {
@autoreleasepool {
[[cocoaView content] reloadData];
}
}
void pListView::setFont(string font) {
@autoreleasepool {
[cocoaView setFont:pFont::cocoaFont(font)];
}
}
void pListView::setForegroundColor(Color color) {
}
void pListView::setHeaderText(const lstring& text) {
@autoreleasepool {
[cocoaView reloadColumns];
}
}
void pListView::setHeaderVisible(bool visible) {
@autoreleasepool {
if(visible) {
[[cocoaView content] setHeaderView:[[[NSTableHeaderView alloc] init] autorelease]];
} else {
[[cocoaView content] setHeaderView:nil];
}
}
}
void pListView::setImage(unsigned selection, unsigned position, const image& image) {
@autoreleasepool {
[[cocoaView content] reloadData];
}
}
void pListView::setSelected(bool selected) {
@autoreleasepool {
if(selected == false) {
[[cocoaView content] deselectAll:nil];
}
}
}
void pListView::setSelection(unsigned selection) {
@autoreleasepool {
[[cocoaView content] selectRowIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(selection, 1)] byExtendingSelection:NO];
}
}
void pListView::setText(unsigned selection, unsigned position, const string text) {
@autoreleasepool {
[[cocoaView content] reloadData];
}
}
void pListView::constructor() {
@autoreleasepool {
cocoaView = cocoaListView = [[CocoaListView alloc] initWith:listView];
setHeaderVisible(listView.state.headerVisible);
setHeaderText(listView.state.headerText);
}
}
void pListView::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,64 @@
@class CocoaListViewContent;
@interface CocoaListView : NSScrollView <NSTableViewDelegate, NSTableViewDataSource> {
@public
phoenix::ListView* listView;
CocoaListViewContent* content;
NSFont* font;
}
-(id) initWith:(phoenix::ListView&)listView;
-(void) dealloc;
-(CocoaListViewContent*) content;
-(NSFont*) font;
-(void) setFont:(NSFont*)font;
-(void) reloadColumns;
-(NSInteger) numberOfRowsInTableView:(NSTableView*)table;
-(id) tableView:(NSTableView*)table objectValueForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row;
-(BOOL) tableView:(NSTableView*)table shouldShowCellExpansionForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row;
-(NSString*) tableView:(NSTableView*)table toolTipForCell:(NSCell*)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row mouseLocation:(NSPoint)mouseLocation;
-(void) tableView:(NSTableView*)table setObjectValue:(id)object forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row;
-(void) tableView:(NSTableView*)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row;
-(void) tableViewSelectionDidChange:(NSNotification*)notification;
-(IBAction) activate:(id)sender;
-(IBAction) doubleAction:(id)sender;
@end
@interface CocoaListViewContent : NSTableView {
}
-(void) keyDown:(NSEvent*)event;
@end
@interface CocoaListViewCell : NSTextFieldCell {
}
-(NSString*) stringValue;
-(void) drawWithFrame:(NSRect)frame inView:(NSView*)view;
@end
namespace phoenix {
struct pListView : public pWidget {
ListView& listView;
CocoaListView* cocoaListView = nullptr;
void append(const lstring& text);
void autoSizeColumns();
void remove(unsigned selection);
void reset();
void setBackgroundColor(Color color);
void setCheckable(bool checkable);
void setChecked(unsigned selection, bool checked);
void setFont(string font);
void setForegroundColor(Color color);
void setHeaderText(const lstring& text);
void setHeaderVisible(bool visible);
void setImage(unsigned selection, unsigned position, const image& image);
void setSelected(bool selected);
void setSelection(unsigned selection);
void setText(unsigned selection, unsigned position, string text);
pListView(ListView& listView) : pWidget(listView), listView(listView) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,37 @@
@implementation CocoaProgressBar : NSProgressIndicator
-(id) initWith:(phoenix::ProgressBar&)progressBarReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
progressBar = &progressBarReference;
[self setIndeterminate:NO];
[self setMinValue:0.0];
[self setMaxValue:100.0];
}
return self;
}
@end
namespace phoenix {
void pProgressBar::setPosition(unsigned position) {
@autoreleasepool {
[cocoaView setDoubleValue:position];
}
}
void pProgressBar::constructor() {
@autoreleasepool {
cocoaView = cocoaProgressBar = [[CocoaProgressBar alloc] initWith:progressBar];
setPosition(progressBar.state.position);
}
}
void pProgressBar::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,21 @@
@interface CocoaProgressBar : NSProgressIndicator {
@public
phoenix::ProgressBar* progressBar;
}
-(id) initWith:(phoenix::ProgressBar&)progressBar;
@end
namespace phoenix {
struct pProgressBar : public pWidget {
ProgressBar& progressBar;
CocoaProgressBar* cocoaProgressBar = nullptr;
void setPosition(unsigned position);
pProgressBar(ProgressBar& progressBar) : pWidget(progressBar), progressBar(progressBar) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,94 @@
@implementation CocoaRadioButton : NSButton
-(id) initWith:(phoenix::RadioButton&)radioButtonReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
radioButton = &radioButtonReference;
[self setTarget:self];
[self setAction:@selector(activate:)];
[self setBezelStyle:NSRegularSquareBezelStyle];
[self setButtonType:NSOnOffButton];
}
return self;
}
-(IBAction) activate:(id)sender {
bool wasChecked = radioButton->state.checked;
radioButton->setChecked();
if(wasChecked == false) {
if(radioButton->onActivate) radioButton->onActivate();
}
}
@end
namespace phoenix {
Size pRadioButton::minimumSize() {
Size size = Font::size(radioButton.font(), radioButton.state.text);
if(radioButton.state.orientation == Orientation::Horizontal) {
size.width += radioButton.state.image.width;
size.height = max(radioButton.state.image.height, size.height);
}
if(radioButton.state.orientation == Orientation::Vertical) {
size.width = max(radioButton.state.image.width, size.width);
size.height += radioButton.state.image.height;
}
return {size.width + 20, size.height + 4};
}
void pRadioButton::setChecked() {
@autoreleasepool {
for(auto& button : radioButton.state.group) {
auto state = (&button == &radioButton) ? NSOnState : NSOffState;
[button.p.cocoaView setState:state];
}
}
}
void pRadioButton::setGeometry(Geometry geometry) {
pWidget::setGeometry({
geometry.x - 2, geometry.y - 2,
geometry.width + 4, geometry.height + 4
});
}
void pRadioButton::setGroup(const group<RadioButton>& group) {
}
void pRadioButton::setImage(const image& image, Orientation orientation) {
@autoreleasepool {
if(image.empty()) {
[cocoaView setImage:nil];
return;
}
[cocoaView setImage:NSMakeImage(image)];
if(orientation == Orientation::Horizontal) [cocoaView setImagePosition:NSImageLeft];
if(orientation == Orientation::Vertical ) [cocoaView setImagePosition:NSImageAbove];
}
}
void pRadioButton::setText(string text) {
@autoreleasepool {
[cocoaView setTitle:[NSString stringWithUTF8String:text]];
}
}
void pRadioButton::constructor() {
@autoreleasepool {
cocoaView = cocoaRadioButton = [[CocoaRadioButton alloc] initWith:radioButton];
}
}
void pRadioButton::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,27 @@
@interface CocoaRadioButton : NSButton {
@public
phoenix::RadioButton* radioButton;
}
-(id) initWith:(phoenix::RadioButton&)radioButton;
-(IBAction) activate:(id)sender;
@end
namespace phoenix {
struct pRadioButton : public pWidget {
RadioButton& radioButton;
CocoaRadioButton* cocoaRadioButton = nullptr;
Size minimumSize();
void setChecked();
void setGeometry(Geometry geometry);
void setGroup(const group<RadioButton>& group);
void setImage(const image& image, Orientation orientation);
void setText(string text);
pRadioButton(RadioButton& radioButton) : pWidget(radioButton), radioButton(radioButton) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,65 @@
@implementation CocoaRadioLabel : NSButton
-(id) initWith:(phoenix::RadioLabel&)radioLabelReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
radioLabel = &radioLabelReference;
[self setTarget:self];
[self setAction:@selector(activate:)];
[self setButtonType:NSRadioButton];
}
return self;
}
-(IBAction) activate:(id)sender {
radioLabel->setChecked();
if(radioLabel->onActivate) radioLabel->onActivate();
}
@end
namespace phoenix {
Size pRadioLabel::minimumSize() {
Size size = Font::size(radioLabel.font(), radioLabel.state.text);
return {size.width + 22, size.height};
}
void pRadioLabel::setChecked() {
@autoreleasepool {
for(auto& item : radioLabel.state.group) {
auto state = (&item == &radioLabel) ? NSOnState : NSOffState;
[item.p.cocoaView setState:state];
}
}
}
void pRadioLabel::setGeometry(Geometry geometry) {
pWidget::setGeometry({
geometry.x - 1, geometry.y,
geometry.width + 2, geometry.height
});
}
void pRadioLabel::setGroup(const group<RadioLabel>& group) {
}
void pRadioLabel::setText(string text) {
@autoreleasepool {
[cocoaView setTitle:[NSString stringWithUTF8String:text]];
}
}
void pRadioLabel::constructor() {
@autoreleasepool {
cocoaView = cocoaRadioLabel = [[CocoaRadioLabel alloc] initWith:radioLabel];
}
}
void pRadioLabel::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,26 @@
@interface CocoaRadioLabel : NSButton {
@public
phoenix::RadioLabel* radioLabel;
}
-(id) initWith:(phoenix::RadioLabel&)radioLabel;
-(IBAction) activate:(id)sender;
@end
namespace phoenix {
struct pRadioLabel : public pWidget {
RadioLabel& radioLabel;
CocoaRadioLabel* cocoaRadioLabel = nullptr;
Size minimumSize();
void setChecked();
void setGeometry(Geometry geometry);
void setGroup(const group<RadioLabel>& group);
void setText(string text);
pRadioLabel(RadioLabel& radioLabel) : pWidget(radioLabel), radioLabel(radioLabel) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,9 @@
namespace phoenix {
struct pSizable : public pObject {
Sizable& sizable;
pSizable(Sizable& sizable) : pObject(sizable), sizable(sizable) {}
};
}

View File

@@ -0,0 +1,145 @@
@implementation CocoaTabFrame : NSTabView
-(id) initWith:(phoenix::TabFrame&)tabFrameReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
tabFrame = &tabFrameReference;
[self setDelegate:self];
}
return self;
}
-(void) tabView:(NSTabView*)tabView didSelectTabViewItem:(NSTabViewItem*)tabViewItem {
tabFrame->state.selection = [tabView indexOfTabViewItem:tabViewItem];
tabFrame->p.synchronizeLayout();
if(tabFrame->onChange) tabFrame->onChange();
}
@end
@implementation CocoaTabFrameItem : NSTabViewItem
-(id) initWith:(phoenix::TabFrame&)tabFrameReference {
if(self = [super initWithIdentifier:nil]) {
tabFrame = &tabFrameReference;
cocoaTabFrame = tabFrame->p.cocoaTabFrame;
}
return self;
}
-(NSSize) sizeOfLabel:(BOOL)shouldTruncateLabel {
NSSize sizeOfLabel = [super sizeOfLabel:shouldTruncateLabel];
signed selection = [cocoaTabFrame indexOfTabViewItem:self];
if(selection < 0) return sizeOfLabel; //should never happen
if(tabFrame->state.image[selection].empty() == false) {
unsigned iconSize = phoenix::Font::size(tabFrame->font(), " ").height;
sizeOfLabel.width += iconSize + 2;
}
return sizeOfLabel;
}
-(void) drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)tabRect {
signed selection = [cocoaTabFrame indexOfTabViewItem:self];
if(selection >= 0 && tabFrame->state.image[selection].empty() == false) {
unsigned iconSize = phoenix::Font::size(tabFrame->font(), " ").height;
NSImage* image = NSMakeImage(tabFrame->state.image[selection]);
[[NSGraphicsContext currentContext] saveGraphicsState];
NSRect targetRect = NSMakeRect(tabRect.origin.x, tabRect.origin.y + 2, iconSize, iconSize);
[image drawInRect:targetRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil];
[[NSGraphicsContext currentContext] restoreGraphicsState];
tabRect.origin.x += iconSize + 2;
tabRect.size.width -= iconSize + 2;
}
[super drawLabel:shouldTruncateLabel inRect:tabRect];
}
@end
namespace phoenix {
void pTabFrame::append(string text, const image& image) {
@autoreleasepool {
CocoaTabFrameItem* item = [[CocoaTabFrameItem alloc] initWith:tabFrame];
[item setLabel:[NSString stringWithUTF8String:text]];
[cocoaView addTabViewItem:item];
tabs.append(item);
}
}
void pTabFrame::remove(unsigned selection) {
@autoreleasepool {
CocoaTabFrameItem* item = tabs[selection];
[cocoaView removeTabViewItem:item];
tabs.remove(selection);
}
}
void pTabFrame::setEnabled(bool enabled) {
for(auto& layout : tabFrame.state.layout) {
if(layout) layout->setEnabled(layout->enabled());
}
pWidget::setEnabled(enabled);
}
void pTabFrame::setGeometry(Geometry geometry) {
pWidget::setGeometry({
geometry.x - 7, geometry.y - 5,
geometry.width + 14, geometry.height + 6
});
geometry.x += 1, geometry.width -= 2;
geometry.y += 22, geometry.height -= 32;
for(auto& layout : tabFrame.state.layout) {
if(layout == nullptr) continue;
layout->setGeometry(geometry);
}
synchronizeLayout();
}
void pTabFrame::setImage(unsigned selection, const image& image) {
}
void pTabFrame::setSelection(unsigned selection) {
@autoreleasepool {
CocoaTabFrameItem* item = tabs[selection];
[cocoaView selectTabViewItem:item];
}
synchronizeLayout();
}
void pTabFrame::setText(unsigned selection, string text) {
@autoreleasepool {
CocoaTabFrameItem* item = tabs[selection];
[item setLabel:[NSString stringWithUTF8String:text]];
}
}
void pTabFrame::setVisible(bool visible) {
for(auto& layout : tabFrame.state.layout) {
if(layout) layout->setVisible(layout->visible());
}
pWidget::setVisible(visible);
}
void pTabFrame::constructor() {
@autoreleasepool {
cocoaView = cocoaTabFrame = [[CocoaTabFrame alloc] initWith:tabFrame];
}
}
void pTabFrame::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
void pTabFrame::synchronizeLayout() {
unsigned selection = 0;
for(auto& layout : tabFrame.state.layout) {
if(layout) layout->setVisible(selection == tabFrame.state.selection);
selection++;
}
}
}

View File

@@ -0,0 +1,41 @@
@interface CocoaTabFrame : NSTabView <NSTabViewDelegate> {
@public
phoenix::TabFrame* tabFrame;
}
-(id) initWith:(phoenix::TabFrame&)tabFrame;
-(void) tabView:(NSTabView*)tabView didSelectTabViewItem:(NSTabViewItem*)tabViewItem;
@end
@interface CocoaTabFrameItem : NSTabViewItem {
@public
phoenix::TabFrame* tabFrame;
CocoaTabFrame* cocoaTabFrame;
}
-(id) initWith:(phoenix::TabFrame&)tabFrame;
-(NSSize) sizeOfLabel:(BOOL)shouldTruncateLabel;
-(void) drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)tabRect;
@end
namespace phoenix {
struct pTabFrame : public pWidget {
TabFrame& tabFrame;
CocoaTabFrame* cocoaTabFrame = nullptr;
vector<CocoaTabFrameItem*> tabs;
void append(string text, const image& image);
void remove(unsigned selection);
void setEnabled(bool enabled);
void setGeometry(Geometry geometry);
void setImage(unsigned selection, const image& image);
void setSelection(unsigned selection);
void setText(unsigned selection, string text);
void setVisible(bool visible);
pTabFrame(TabFrame& tabFrame) : pWidget(tabFrame), tabFrame(tabFrame) {}
void constructor();
void destructor();
void synchronizeLayout();
};
}

View File

@@ -0,0 +1,107 @@
@implementation CocoaTextEdit : NSScrollView
-(id) initWith:(phoenix::TextEdit&)textEditReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
textEdit = &textEditReference;
content = [[[NSTextView alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)] autorelease];
[content setDelegate:self];
[content setRichText:NO];
[self setBorderType:NSBezelBorder];
[self setDocumentView:content];
[self configure];
}
return self;
}
-(NSTextView*) content {
return content;
}
-(void) configure {
[content setMinSize:NSMakeSize(0, 0)];
[content setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
[[content textContainer] setContainerSize:NSMakeSize(FLT_MAX, FLT_MAX)];
[[content textContainer] setWidthTracksTextView:textEdit->wordWrap()];
[content setHorizontallyResizable:YES];
[content setVerticallyResizable:YES];
[content setAutoresizingMask:NSViewNotSizable];
[self setHasHorizontalScroller:!textEdit->wordWrap()];
[self setHasVerticalScroller:YES];
}
-(void) textDidChange:(NSNotification*)notification {
textEdit->state.text = [[content string] UTF8String];
if(textEdit->onChange) textEdit->onChange();
}
@end
namespace phoenix {
void pTextEdit::setBackgroundColor(Color color) {
}
void pTextEdit::setCursorPosition(unsigned position) {
@autoreleasepool {
string text = [[[cocoaView content] string] UTF8String];
position = min(position, text.length());
[[cocoaView content] setSelectedRange:NSMakeRange(position, 0)];
}
}
void pTextEdit::setEditable(bool editable) {
@autoreleasepool {
[[cocoaView content] setEditable:editable];
}
}
void pTextEdit::setFont(string font) {
@autoreleasepool {
[[cocoaView content] setFont:pFont::cocoaFont(font)];
}
}
void pTextEdit::setForegroundColor(Color color) {
}
void pTextEdit::setText(string text) {
@autoreleasepool {
[[cocoaView content] setString:[NSString stringWithUTF8String:text]];
}
}
void pTextEdit::setWordWrap(bool wordWrap) {
@autoreleasepool {
[cocoaView configure];
}
}
string pTextEdit::text() {
@autoreleasepool {
return [[[cocoaView content] string] UTF8String];
}
}
void pTextEdit::constructor() {
@autoreleasepool {
cocoaView = cocoaTextEdit = [[CocoaTextEdit alloc] initWith:textEdit];
setEditable(textEdit.state.editable);
setWordWrap(textEdit.state.wordWrap);
setFont(textEdit.font());
setText(textEdit.state.text);
setCursorPosition(textEdit.state.cursorPosition);
}
}
void pTextEdit::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,32 @@
@interface CocoaTextEdit : NSScrollView <NSTextViewDelegate> {
@public
phoenix::TextEdit* textEdit;
NSTextView* content;
}
-(id) initWith:(phoenix::TextEdit&)textEdit;
-(NSTextView*) content;
-(void) configure;
-(void) textDidChange:(NSNotification*)notification;
@end
namespace phoenix {
struct pTextEdit : public pWidget {
TextEdit& textEdit;
CocoaTextEdit* cocoaTextEdit = nullptr;
void setBackgroundColor(Color color);
void setCursorPosition(unsigned position);
void setEditable(bool editable);
void setFont(string font);
void setForegroundColor(Color color);
void setText(string text);
void setWordWrap(bool wordWrap);
string text();
pTextEdit(TextEdit& textEdit) : pWidget(textEdit), textEdit(textEdit) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,85 @@
@implementation CocoaVerticalScroller : NSScroller
-(id) initWith:(phoenix::VerticalScroller&)verticalScrollerReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 1)]) {
verticalScroller = &verticalScrollerReference;
[self setTarget:self];
[self setAction:@selector(scroll:)];
[self setControlSize:NSRegularControlSize];
[self setScrollerStyle:NSScrollerStyleLegacy];
[self setEnabled:YES];
[self update];
}
return self;
}
-(void) update {
double d = 1.0 / verticalScroller->state.length;
double f = d * verticalScroller->state.position;
[self setDoubleValue:f];
[self setKnobProportion:d];
}
-(IBAction) scroll:(id)sender {
auto& state = verticalScroller->state;
switch([self hitPart]) {
case NSScrollerIncrementLine:
case NSScrollerIncrementPage:
if(state.position < state.length - 1) state.position++;
[self update];
break;
case NSScrollerDecrementLine:
case NSScrollerDecrementPage:
if(state.position) state.position--;
[self update];
break;
case NSScrollerKnob:
state.position = [self doubleValue] * state.length;
break;
}
if(verticalScroller->onChange) verticalScroller->onChange();
}
@end
namespace phoenix {
Size pVerticalScroller::minimumSize() {
@autoreleasepool {
return {[NSScroller scrollerWidthForControlSize:NSRegularControlSize scrollerStyle:NSScrollerStyleLegacy], 32};
}
}
void pVerticalScroller::setLength(unsigned length) {
@autoreleasepool {
[cocoaView update];
}
}
void pVerticalScroller::setPosition(unsigned position) {
@autoreleasepool {
[cocoaView update];
}
}
void pVerticalScroller::constructor() {
@autoreleasepool {
cocoaView = cocoaVerticalScroller = [[CocoaVerticalScroller alloc] initWith:verticalScroller];
}
}
void pVerticalScroller::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,25 @@
@interface CocoaVerticalScroller : NSScroller {
@public
phoenix::VerticalScroller* verticalScroller;
}
-(id) initWith:(phoenix::VerticalScroller&)verticalScroller;
-(void) update;
-(IBAction) scroll:(id)sender;
@end
namespace phoenix {
struct pVerticalScroller : public pWidget {
VerticalScroller& verticalScroller;
CocoaVerticalScroller* cocoaVerticalScroller = nullptr;
Size minimumSize();
void setLength(unsigned length);
void setPosition(unsigned position);
pVerticalScroller(VerticalScroller& verticalScroller) : pWidget(verticalScroller), verticalScroller(verticalScroller) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,61 @@
@implementation CocoaVerticalSlider : NSSlider
-(id) initWith:(phoenix::VerticalSlider&)verticalSliderReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 1)]) {
verticalSlider = &verticalSliderReference;
[self setTarget:self];
[self setAction:@selector(activate:)];
[self setMinValue:0];
}
return self;
}
-(IBAction) activate:(id)sender {
verticalSlider->state.position = [self doubleValue];
if(verticalSlider->onChange) verticalSlider->onChange();
}
@end
namespace phoenix {
Size pVerticalSlider::minimumSize() {
return {20, 48};
}
void pVerticalSlider::setGeometry(Geometry geometry) {
pWidget::setGeometry({
geometry.x, geometry.y - 2,
geometry.width, geometry.height + 4
});
}
void pVerticalSlider::setLength(unsigned length) {
@autoreleasepool {
[cocoaView setMaxValue:length];
}
}
void pVerticalSlider::setPosition(unsigned position) {
@autoreleasepool {
[cocoaView setDoubleValue:position];
}
}
void pVerticalSlider::constructor() {
@autoreleasepool {
cocoaView = cocoaVerticalSlider = [[CocoaVerticalSlider alloc] initWith:verticalSlider];
setLength(verticalSlider.state.length);
setPosition(verticalSlider.state.position);
}
}
void pVerticalSlider::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,25 @@
@interface CocoaVerticalSlider : NSSlider {
@public
phoenix::VerticalSlider* verticalSlider;
}
-(id) initWith:(phoenix::VerticalSlider&)verticalSlider;
-(IBAction) activate:(id)sender;
@end
namespace phoenix {
struct pVerticalSlider : public pWidget {
VerticalSlider& verticalSlider;
CocoaVerticalSlider* cocoaVerticalSlider = nullptr;
Size minimumSize();
void setGeometry(Geometry geometry);
void setLength(unsigned length);
void setPosition(unsigned position);
pVerticalSlider(VerticalSlider& verticalSlider) : pWidget(verticalSlider), verticalSlider(verticalSlider) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,66 @@
@implementation CocoaViewport : NSView
-(id) initWith:(phoenix::Viewport&)viewportReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
viewport = &viewportReference;
}
return self;
}
-(void) drawRect:(NSRect)rect {
[[NSColor blackColor] setFill];
NSRectFillUsingOperation(rect, NSCompositeSourceOver);
}
-(BOOL) acceptsFirstResponder {
return YES;
}
-(NSDragOperation) draggingEntered:(id<NSDraggingInfo>)sender {
return DropPathsOperation(sender);
}
-(BOOL) performDragOperation:(id<NSDraggingInfo>)sender {
lstring paths = DropPaths(sender);
if(paths.empty()) return NO;
if(viewport->onDrop) viewport->onDrop(paths);
return YES;
}
-(void) keyDown:(NSEvent*)event {
}
-(void) keyUp:(NSEvent*)event {
}
@end
namespace phoenix {
uintptr_t pViewport::handle() {
return (uintptr_t)cocoaViewport;
}
void pViewport::setDroppable(bool droppable) {
@autoreleasepool {
if(droppable) {
[cocoaViewport registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
} else {
[cocoaViewport unregisterDraggedTypes];
}
}
}
void pViewport::constructor() {
@autoreleasepool {
cocoaView = cocoaViewport = [[CocoaViewport alloc] initWith:viewport];
}
}
void pViewport::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,28 @@
@interface CocoaViewport : NSView {
@public
phoenix::Viewport* viewport;
}
-(id) initWith:(phoenix::Viewport&)viewport;
-(void) drawRect:(NSRect)rect;
-(BOOL) acceptsFirstResponder;
-(NSDragOperation) draggingEntered:(id<NSDraggingInfo>)sender;
-(BOOL) performDragOperation:(id<NSDraggingInfo>)sender;
-(void) keyDown:(NSEvent*)event;
-(void) keyUp:(NSEvent*)event;
@end
namespace phoenix {
struct pViewport : public pWidget {
Viewport& viewport;
CocoaViewport* cocoaViewport = nullptr;
uintptr_t handle();
void setDroppable(bool droppable);
pViewport(Viewport& viewport) : pWidget(viewport), viewport(viewport) {}
void constructor();
void destructor();
};
}

View File

@@ -0,0 +1,79 @@
namespace phoenix {
bool pWidget::enabled() {
@autoreleasepool {
return [cocoaView respondsToSelector:@selector(enabled)] && [cocoaView enabled];
}
}
bool pWidget::focused() {
@autoreleasepool {
return cocoaView == [[cocoaView window] firstResponder];
}
}
Size pWidget::minimumSize() {
return {0, 0};
}
void pWidget::setEnabled(bool enabled) {
if(!widget.parent()) enabled = false;
if(widget.state.abstract) enabled = false;
if(!widget.enabledToAll()) enabled = false;
@autoreleasepool {
if([cocoaView respondsToSelector:@selector(setEnabled:)]) {
[cocoaView setEnabled:enabled];
}
}
}
void pWidget::setFocused() {
@autoreleasepool {
[[cocoaView window] makeFirstResponder:cocoaView];
}
}
void pWidget::setFont(string font) {
@autoreleasepool {
if([cocoaView respondsToSelector:@selector(setFont:)]) {
[cocoaView setFont:pFont::cocoaFont(font)];
}
}
}
void pWidget::setGeometry(Geometry geometry) {
@autoreleasepool {
CGFloat windowHeight = [[cocoaView superview] frame].size.height;
[cocoaView setFrame:NSMakeRect(geometry.x, windowHeight - geometry.y - geometry.height, geometry.width, geometry.height)];
[[cocoaView superview] setNeedsDisplay:YES];
}
if(widget.onSize) widget.onSize();
}
void pWidget::setVisible(bool visible) {
if(!widget.parent()) visible = false;
if(widget.state.abstract) visible = false;
if(!widget.visibleToAll()) visible = false;
@autoreleasepool {
[cocoaView setHidden:!visible];
}
}
void pWidget::constructor() {
if(!widget.state.abstract) return;
@autoreleasepool {
cocoaView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)];
[cocoaView setHidden:true];
}
}
void pWidget::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@@ -0,0 +1,21 @@
namespace phoenix {
struct pWidget : public pSizable {
Widget& widget;
NSView* cocoaView = nullptr;
bool enabled();
bool focused();
virtual Size minimumSize();
virtual void setEnabled(bool enabled);
void setFocused();
virtual void setFont(string font);
virtual void setGeometry(Geometry geometry);
virtual void setVisible(bool visible);
pWidget(Widget& widget) : pSizable(widget), widget(widget) {}
void constructor();
void destructor();
};
}