2013-03-15 13:11:33 +00:00
|
|
|
@implementation CocoaCanvas : NSImageView
|
|
|
|
|
2013-03-21 12:59:01 +00:00
|
|
|
-(id) initWith:(phoenix::Canvas&)canvasReference {
|
2013-03-15 13:11:33 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2013-03-21 12:59:01 +00:00
|
|
|
-(void) mouseButton:(NSEvent*)event down:(BOOL)isDown {
|
2013-03-15 13:11:33 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-21 12:59:01 +00:00
|
|
|
-(void) mouseExited:(NSEvent*)event {
|
2013-03-15 13:11:33 +00:00
|
|
|
if(canvas->onMouseLeave) canvas->onMouseLeave();
|
|
|
|
}
|
|
|
|
|
2013-03-21 12:59:01 +00:00
|
|
|
-(void) mouseMove:(NSEvent*)event {
|
2013-03-15 13:11:33 +00:00
|
|
|
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});
|
|
|
|
}
|
|
|
|
|
2013-03-21 12:59:01 +00:00
|
|
|
-(void) mouseDown:(NSEvent*)event {
|
2013-03-15 13:11:33 +00:00
|
|
|
[self mouseButton:event down:YES];
|
|
|
|
}
|
|
|
|
|
2013-03-21 12:59:01 +00:00
|
|
|
-(void) mouseUp:(NSEvent*)event {
|
2013-03-15 13:11:33 +00:00
|
|
|
[self mouseButton:event down:NO];
|
|
|
|
}
|
|
|
|
|
2013-03-21 12:59:01 +00:00
|
|
|
-(void) mouseDragged:(NSEvent*)event {
|
2013-03-15 13:11:33 +00:00
|
|
|
[self mouseMove:event];
|
|
|
|
}
|
|
|
|
|
2013-03-21 12:59:01 +00:00
|
|
|
-(void) rightMouseDown:(NSEvent*)event {
|
2013-03-15 13:11:33 +00:00
|
|
|
[self mouseButton:event down:YES];
|
|
|
|
}
|
|
|
|
|
2013-03-21 12:59:01 +00:00
|
|
|
-(void) rightMouseUp:(NSEvent*)event {
|
2013-03-15 13:11:33 +00:00
|
|
|
[self mouseButton:event down:NO];
|
|
|
|
}
|
|
|
|
|
2013-03-21 12:59:01 +00:00
|
|
|
-(void) rightMouseDragged:(NSEvent*)event {
|
2013-03-15 13:11:33 +00:00
|
|
|
[self mouseMove:event];
|
|
|
|
}
|
|
|
|
|
2013-03-21 12:59:01 +00:00
|
|
|
-(void) otherMouseDown:(NSEvent*)event {
|
2013-03-15 13:11:33 +00:00
|
|
|
[self mouseButton:event down:YES];
|
|
|
|
}
|
|
|
|
|
2013-03-21 12:59:01 +00:00
|
|
|
-(void) otherMouseUp:(NSEvent*)event {
|
2013-03-15 13:11:33 +00:00
|
|
|
[self mouseButton:event down:NO];
|
|
|
|
}
|
|
|
|
|
2013-03-21 12:59:01 +00:00
|
|
|
-(void) otherMouseDragged:(NSEvent*)event {
|
2013-03-15 13:11:33 +00:00
|
|
|
[self mouseMove:event];
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
namespace phoenix {
|
|
|
|
|
|
|
|
void pCanvas::setSize(const Size &size) {
|
|
|
|
@autoreleasepool {
|
|
|
|
NSImage *image = [[[NSImage alloc] initWithSize:NSMakeSize(size.width, size.height)] autorelease];
|
|
|
|
NSBitmapImageRep *bitmap = [[[NSBitmapImageRep alloc]
|
|
|
|
initWithBitmapDataPlanes:nil
|
|
|
|
pixelsWide:size.width pixelsHigh:size.height
|
|
|
|
bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES
|
|
|
|
isPlanar:NO colorSpaceName:NSCalibratedRGBColorSpace
|
|
|
|
bitmapFormat:NSAlphaNonpremultipliedBitmapFormat
|
|
|
|
bytesPerRow:size.width * 4 bitsPerPixel:32
|
|
|
|
] autorelease];
|
|
|
|
|
|
|
|
[image addRepresentation:bitmap];
|
|
|
|
[cocoaView setImage:image];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void pCanvas::update() {
|
|
|
|
@autoreleasepool {
|
|
|
|
if(NSBitmapImageRep *bitmap = [[[cocoaView image] representations] objectAtIndex:0]) {
|
|
|
|
uint8_t *target = [bitmap bitmapData];
|
|
|
|
uint32_t *source = canvas.state.data;
|
|
|
|
|
|
|
|
for(unsigned n = 0; n < canvas.state.width * canvas.state.height; n++) {
|
|
|
|
*target++ = *source >> 16;
|
|
|
|
*target++ = *source >> 8;
|
|
|
|
*target++ = *source >> 0;
|
|
|
|
*target++ = *source >> 24;
|
|
|
|
source++;
|
|
|
|
}
|
|
|
|
|
|
|
|
[cocoaView setNeedsDisplay:YES];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void pCanvas::constructor() {
|
|
|
|
@autoreleasepool {
|
|
|
|
cocoaView = cocoaCanvas = [[CocoaCanvas alloc] initWith:canvas];
|
|
|
|
setSize(canvas.size());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void pCanvas::destructor() {
|
|
|
|
@autoreleasepool {
|
|
|
|
[cocoaView release];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|