From 21a5cd6d814a913df4cd17b12a7feb5397d65179 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sun, 4 Dec 2016 19:25:17 +0100 Subject: Cocoa for the masses. --- plugingui/nativewindow_cocoa.mm | 360 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 plugingui/nativewindow_cocoa.mm (limited to 'plugingui/nativewindow_cocoa.mm') diff --git a/plugingui/nativewindow_cocoa.mm b/plugingui/nativewindow_cocoa.mm new file mode 100644 index 0000000..531c2a8 --- /dev/null +++ b/plugingui/nativewindow_cocoa.mm @@ -0,0 +1,360 @@ +/* -*- Mode: ObjC; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * nativewindow_cocoa.mm + * + * Fri Dec 2 20:31:03 CET 2016 + * Copyright 2016 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of DrumGizmo. + * + * DrumGizmo is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DrumGizmo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with DrumGizmo; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +/* + +loop: +http://stackoverflow.com/questions/6732400/cocoa-integrate-nsapplication-into-an-existing-c-mainloop + +draw pixels: +http://stackoverflow.com/questions/10955913/how-can-i-display-an-array-of-pixels-on-a-nswindow +*/ + +#include +#include + +#import + +bool running = true; + +@interface MyWindow : NSWindow +{ +@public + // MyView* my_view; +} + +- (id) initWithContentRect:(NSRect)contentRect + styleMask:(unsigned int)aStyle + backing:(NSBackingStoreType)bufferingType + defer:(BOOL)flag; +//- (void) setMyView:(MyView*)view; +- (BOOL) windowShouldClose:(id)sender; +- (void) mouseMoved:(NSEvent*)event; +- (void) drawRect:(NSRect)dirtyRect; +@end + +@implementation MyWindow + +- (id)initWithContentRect:(NSRect)contentRect + styleMask:(unsigned int)aStyle + backing:(NSBackingStoreType)bufferingType + defer:(BOOL)flag +{ + NSWindow* result = [super initWithContentRect:contentRect + styleMask:(NSClosableWindowMask | + NSTitledWindowMask | + NSResizableWindowMask) + backing:NSBackingStoreBuffered defer:NO]; + + [result setAcceptsMouseMovedEvents:YES]; + [result setLevel: CGShieldingWindowLevel() + 1]; + + return result; +} + +//- (void)setMyView:(MyView*)view +//{ +// //my_view = view; +// //[self setContentSize:NSMakeSize(view->width, view->height) ]; +//} + +- (BOOL)windowShouldClose:(id)sender +{ + printf("closing!\n"); + //if (puglview->closeFunc) + // puglview->closeFunc(puglview); + running = false; + return YES; +} + +#define WIDTH 100 +#define HEIGHT 100 +#define SIZE (WIDTH*HEIGHT) +#define BYTES_PER_PIXEL 2 +#define BITS_PER_COMPONENT 5 +#define BITS_PER_PIXEL 16 + +- (void)drawRect:(NSRect)dirtyRect +{ +} +- (void) mouseMoved:(NSEvent*)event +{ + /* + if (puglview->motionFunc) { + NSPoint loc = [event locationInWindow]; + puglview->mods = getModifiers(puglview, event); + puglview->motionFunc(puglview, loc.x, puglview->height - loc.y); + } + */ + NSPoint loc = [event locationInWindow]; + printf("mouseMove: %f %f\n", loc.x, loc.y); +} + +@end + + + + +@interface MyView : NSView +{ + int colorBits; + int depthBits; +@public + //PuglView* puglview; + + NSTrackingArea* trackingArea; +} + +- (id) initWithFrame:(NSRect)frame + colorBits:(int)numColorBits + depthBits:(int)numDepthBits; +- (void) reshape; +- (void) drawRect:(NSRect)rect; + +@end +@implementation MyView + +- (id) initWithFrame:(NSRect)frame + colorBits:(int)numColorBits + depthBits:(int)numDepthBits +{ + colorBits = numColorBits; + depthBits = numDepthBits; + + //NSOpenGLPixelFormatAttribute pixelAttribs[16] = { + // NSOpenGLPFADoubleBuffer, + // NSOpenGLPFAAccelerated, + // NSOpenGLPFAColorSize, + // colorBits, + // NSOpenGLPFADepthSize, + // depthBits, + // 0 + //}; + // + //NSOpenGLPixelFormat* pixelFormat = [[NSOpenGLPixelFormat alloc] + // initWithAttributes:pixelAttribs]; + // + //if (pixelFormat) { + // self = [super initWithFrame:frame pixelFormat:pixelFormat]; + // [pixelFormat release]; + // if (self) { + // [[self openGLContext] makeCurrentContext]; + // [self reshape]; + // } + //} else { + // self = nil; + //} + + return self; +} +- (void) reshape +{ + //[[self openGLContext] update]; + // + //NSRect bounds = [self bounds]; + //int width = bounds.size.width; + //int height = bounds.size.height; + // + //if (puglview) { + // /* NOTE: Apparently reshape gets called when the GC gets around to + // deleting the view (?), so we must have reset puglview to NULL when + // this comes around. + // */ + // if (puglview->reshapeFunc) { + // puglview->reshapeFunc(puglview, width, height); + // } else { + // puglDefaultReshape(puglview, width, height); + // } + // + // puglview->width = width; + // puglview->height = height; + //} +} +- (void) drawRect:(NSRect)rect +{ + printf("drawRect\n"); + + // Get current context + CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; + + // Colorspace RGB + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + + // Pixel Matrix allocation + unsigned short *pixels = calloc(SIZE, sizeof(unsigned short)); + + // Random pixels will give you a non-organized RAINBOW + for (int i = 0; i < WIDTH; i++) { + for (int j = 0; j < HEIGHT; j++) { + pixels[i+ j*HEIGHT] = arc4random() % USHRT_MAX; + } + } + + // Provider + CGDataProviderRef provider = CGDataProviderCreateWithData(nil, pixels, SIZE, nil); + + // CGImage + CGImageRef image = CGImageCreate(WIDTH, + HEIGHT, + BITS_PER_COMPONENT, + BITS_PER_PIXEL, + BYTES_PER_PIXEL*WIDTH, + colorSpace, + kCGImageAlphaNoneSkipFirst, + // xRRRRRGGGGGBBBBB - 16-bits, first bit is ignored! + provider, + nil, //No decode + NO, //No interpolation + kCGRenderingIntentDefault); // Default rendering + + // Draw + CGContextDrawImage(context, CGRectMake(0, 0, WIDTH, HEIGHT), image); + + // Once everything is written on screen we can release everything + CGImageRelease(image); + CGColorSpaceRelease(colorSpace); + CGDataProviderRelease(provider); +} +@end + +#include "window.h" + +namespace GUI +{ + +NativeWindowCocoa::NativeWindowCocoa(void* native_window, Window& window) + : buffer(nullptr) + , window(window) +{ + [NSAutoreleasePool new]; + [NSApplication sharedApplication]; + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + /* + id menubar = [[NSMenu new] autorelease]; + id appMenuItem = [[NSMenuItem new] autorelease]; + [menubar addItem:appMenuItem]; + [NSApp setMainMenu:menubar]; + id appMenu = [[NSMenu new] autorelease]; + id appName = [[NSProcessInfo processInfo] processName]; + id quitTitle = [@"Quit " stringByAppendingString:appName]; + id quitMenuItem = [[[NSMenuItem alloc] initWithTitle:quitTitle + action:@selector(terminate:) keyEquivalent:@"q"] autorelease]; + [appMenu addItem:quitMenuItem]; + [appMenuItem setSubmenu:appMenu]; + */ + id window = [[[MyWindow alloc] initWithContentRect:NSMakeRect(0, 0, 200, 200) + styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO] + autorelease]; + [window cascadeTopLeftFromPoint:NSMakePoint(20,20)]; + // [window setTitle:appName]; + [window makeKeyAndOrderFront:nil]; + + id my_view = [MyView new]; + [window setContentView:my_view]; + [NSApp activateIgnoringOtherApps:YES]; + [window makeFirstResponder:my_view]; + + // [NSApp run]; +} + +NativeWindowCocoa::~NativeWindowCocoa() +{ +} + +void NativeWindowCocoa::setFixedSize(int width, int height) +{ +} + +void NativeWindowCocoa::resize(int width, int height) +{ +} + +void NativeWindowCocoa::move(int x, int y) +{ +} + +void NativeWindowCocoa::show() +{ +} + +void NativeWindowCocoa::hide() +{ +} + +void NativeWindowCocoa::handleBuffer() +{ +} + +void NativeWindowCocoa::redraw() +{ +} + +void NativeWindowCocoa::setCaption(const std::string &caption) +{ +} + +void NativeWindowCocoa::grabMouse(bool grab) +{ +} + +bool NativeWindowCocoa::hasEvent() +{ + return false; +} + +std::shared_ptr NativeWindowCocoa::getNextEvent() +{ + //[window setNeedsDisplay: YES]; + + while(running) { + NSEvent * event; + + do + { + event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefa\ +ultRunLoopMode dequeue:YES]; + + + //Convert the cocoa events to something useful here and add them to your own event queue + + [NSApp sendEvent: event]; + } + while(event != nil); + + //printf("loop\n"); + usleep(10000); + } + + return nullptr; +} + +std::shared_ptr NativeWindowCocoa::peekNextEvent() +{ + return nullptr; +} + +} // GUI:: -- cgit v1.2.3