diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2016-12-04 19:25:17 +0100 | 
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2017-01-21 14:51:33 +0100 | 
| commit | 21a5cd6d814a913df4cd17b12a7feb5397d65179 (patch) | |
| tree | 6d8c4a719c5b14abbeb041b389f0418cff68f151 /plugingui | |
| parent | ea6883e9ba851db5e6557b1d71d1268f6ab25c64 (diff) | |
Cocoa for the masses.
Diffstat (limited to 'plugingui')
| -rw-r--r-- | plugingui/Makefile.am.plugingui | 13 | ||||
| -rw-r--r-- | plugingui/nativewindow_cocoa.h | 60 | ||||
| -rw-r--r-- | plugingui/nativewindow_cocoa.mm | 360 | ||||
| -rw-r--r-- | plugingui/window.cc | 6 | 
4 files changed, 436 insertions, 3 deletions
| diff --git a/plugingui/Makefile.am.plugingui b/plugingui/Makefile.am.plugingui index d790f64..22ca3d9 100644 --- a/plugingui/Makefile.am.plugingui +++ b/plugingui/Makefile.am.plugingui @@ -58,17 +58,24 @@ PLUGIN_GUI_CPPFLAGS = \  	-DLODEPNG_NO_COMPILE_CPP  if ENABLE_X11 -PLUGIN_GUI_SOURCES += $(top_srcdir)/plugingui/nativewindow_x11.cc +PLUGIN_GUI_SOURCES += \ +	$(top_srcdir)/plugingui/nativewindow_x11.cc  endif  if ENABLE_WIN32 -PLUGIN_GUI_SOURCES += $(top_srcdir)/plugingui/nativewindow_win32.cc +PLUGIN_GUI_SOURCES += \ +	$(top_srcdir)/plugingui/nativewindow_win32.cc  endif  if ENABLE_PUGL  PLUGIN_GUI_SOURCES += \  	$(top_srcdir)/plugingui/nativewindow_pugl.cc \  	$(top_srcdir)/pugl/pugl/pugl_x11.c -  PLUGIN_GUI_CPPFLAGS += -I$(top_srcdir)/pugl/pugl  endif + +if ENABLE_COCOA +PLUGIN_GUI_SOURCES += \ +	$(top_srcdir)/plugingui/nativewindow_cocoa.m \ +	$(top_srcdir)/plugingui/nativewindow_cocoa.cc +endif diff --git a/plugingui/nativewindow_cocoa.h b/plugingui/nativewindow_cocoa.h new file mode 100644 index 0000000..100b3c7 --- /dev/null +++ b/plugingui/nativewindow_cocoa.h @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            nativewindow_cocoa.h + * + *  Sun Dec  4 15:55:14 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. + */ +#pragma once + +#include "nativewindow.h" + +namespace GUI +{ + +class Window; +class NativeWindowCocoa +	: public NativeWindow +{ +public: +	NativeWindowCocoa(void* native_window, Window& window); +	~NativeWindowCocoa(); + +	// From NativeWindow: +	void setFixedSize(int width, int height) override; +	void resize(int width, int height) override; +	void move(int x, int y) override; +	void show() override; +	void hide() override; +	void setCaption(const std::string &caption) override; +	void handleBuffer() override; +	void redraw() override; +	void grabMouse(bool grab) override; +	bool hasEvent() override; +	std::shared_ptr<Event> getNextEvent() override; +	std::shared_ptr<Event> peekNextEvent() override; + +private: +	Window& window; +}; + +} // GUI:: 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 <stdio.h> +#include <unistd.h> + +#import <Cocoa/Cocoa.h> + +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<Event> 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<Event> NativeWindowCocoa::peekNextEvent() +{ +	return nullptr; +} + +} // GUI:: diff --git a/plugingui/window.cc b/plugingui/window.cc index f8232ad..5d929b2 100644 --- a/plugingui/window.cc +++ b/plugingui/window.cc @@ -35,6 +35,9 @@  #ifdef WIN32  #include "nativewindow_win32.h"  #endif/*WIN32*/ +#ifdef COCOA +#include "nativewindow_cocoa.h" +#endif/*COCOA*/  #else  #include "nativewindow_pugl.h"  #endif @@ -56,6 +59,9 @@ Window::Window(void* native_window)  #ifdef WIN32  	native = new NativeWindowWin32(native_window, *this);  #endif/*WIN32*/ +#ifdef COCOA +	native = new NativeWindowCocoa(native_window, *this); +#endif/*COCOA*/  #else/*Use pugl*/  	native = new NativeWindowPugl(native_window, *this);  #endif | 
