summaryrefslogtreecommitdiff
path: root/plugingui
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2016-12-04 19:25:17 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2017-01-21 14:51:33 +0100
commit21a5cd6d814a913df4cd17b12a7feb5397d65179 (patch)
tree6d8c4a719c5b14abbeb041b389f0418cff68f151 /plugingui
parentea6883e9ba851db5e6557b1d71d1268f6ab25c64 (diff)
Cocoa for the masses.
Diffstat (limited to 'plugingui')
-rw-r--r--plugingui/Makefile.am.plugingui13
-rw-r--r--plugingui/nativewindow_cocoa.h60
-rw-r--r--plugingui/nativewindow_cocoa.mm360
-rw-r--r--plugingui/window.cc6
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