minifb-zig-port/src/macosx/OSXWindow.m
2020-05-17 19:48:59 +02:00

315 lines
9.9 KiB
Objective-C

#import "OSXWindow.h"
#import "OSXView.h"
#include "WindowData_OSX.h"
#include <MiniFB_internal.h>
#include <MiniFB_enums.h>
@implementation OSXWindow
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (id)initWithContentRect:(NSRect)contentRect
styleMask:(NSWindowStyleMask)windowStyle
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)deferCreation
windowData:(SWindowData *) windowData
{
self = [super
initWithContentRect:contentRect
styleMask:windowStyle
backing:bufferingType
defer:deferCreation];
if (self)
{
[self setOpaque:YES];
[self setBackgroundColor:[NSColor clearColor]];
self.delegate = self;
self->window_data = windowData;
OSXView *view = (OSXView *) self->childContentView.superview;
view->window_data = windowData;
}
return self;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void) removeWindowData {
self->window_data = 0x0;
OSXView *view = (OSXView *) self->childContentView.superview;
view->window_data = 0x0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)dealloc
{
[[NSNotificationCenter defaultCenter]
removeObserver:self];
[super dealloc];
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setContentSize:(NSSize)newSize
{
NSSize sizeDelta = newSize;
NSSize childBoundsSize = [childContentView bounds].size;
sizeDelta.width -= childBoundsSize.width;
sizeDelta.height -= childBoundsSize.height;
OSXView *frameView = [super contentView];
NSSize newFrameSize = [frameView bounds].size;
newFrameSize.width += sizeDelta.width;
newFrameSize.height += sizeDelta.height;
[super setContentSize:newFrameSize];
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)flagsChanged:(NSEvent *)event
{
if(window_data == 0x0)
return;
const uint32_t flags = [event modifierFlags];
uint32_t mod_keys = 0, mod_keys_aux = 0;
//NSEventModifierFlagHelp = 1 << 22,
//NSEventModifierFlagFunction = 1 << 23,
if(flags & NSEventModifierFlagCapsLock) {
mod_keys |= KB_MOD_CAPS_LOCK;
}
if(flags & NSEventModifierFlagShift) {
mod_keys |= KB_MOD_SHIFT;
}
if(flags & NSEventModifierFlagControl) {
mod_keys |= KB_MOD_CONTROL;
}
if(flags & NSEventModifierFlagOption) {
mod_keys |= KB_MOD_ALT;
}
if(flags & NSEventModifierFlagCommand) {
mod_keys |= KB_MOD_SUPER;
}
if(flags & NSEventModifierFlagNumericPad) {
mod_keys |= KB_MOD_NUM_LOCK;
}
if(mod_keys != window_data->mod_keys) {
short int key_code = g_keycodes[[event keyCode] & 0x1ff];
if(key_code != KB_KEY_UNKNOWN) {
mod_keys_aux = mod_keys ^ window_data->mod_keys;
if(mod_keys_aux & KB_MOD_CAPS_LOCK) {
window_data->key_status[key_code] = (mod_keys & KB_MOD_CAPS_LOCK) != 0;
kCall(keyboard_func, key_code, mod_keys, window_data->key_status[key_code]);
}
if(mod_keys_aux & KB_MOD_SHIFT) {
window_data->key_status[key_code] = (mod_keys & KB_MOD_SHIFT) != 0;
kCall(keyboard_func, key_code, mod_keys, window_data->key_status[key_code]);
}
if(mod_keys_aux & KB_MOD_CONTROL) {
window_data->key_status[key_code] = (mod_keys & KB_MOD_CONTROL) != 0;
kCall(keyboard_func, key_code, mod_keys, window_data->key_status[key_code]);
}
if(mod_keys_aux & KB_MOD_ALT) {
window_data->key_status[key_code] = (mod_keys & KB_MOD_ALT) != 0;
kCall(keyboard_func, key_code, mod_keys, window_data->key_status[key_code]);
}
if(mod_keys_aux & KB_MOD_SUPER) {
window_data->key_status[key_code] = (mod_keys & KB_MOD_SUPER) != 0;
kCall(keyboard_func, key_code, mod_keys, window_data->key_status[key_code]);
}
if(mod_keys_aux & KB_MOD_NUM_LOCK) {
window_data->key_status[key_code] = (mod_keys & KB_MOD_NUM_LOCK) != 0;
kCall(keyboard_func, key_code, mod_keys, window_data->key_status[key_code]);
}
}
}
window_data->mod_keys = mod_keys;
[super flagsChanged:event];
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)keyDown:(NSEvent *)event
{
if(window_data != 0x0) {
short int key_code = g_keycodes[[event keyCode] & 0x1ff];
window_data->key_status[key_code] = true;
kCall(keyboard_func, key_code, window_data->mod_keys, true);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)keyUp:(NSEvent *)event
{
if(window_data != 0x0) {
short int key_code = g_keycodes[[event keyCode] & 0x1ff];
window_data->key_status[key_code] = false;
kCall(keyboard_func, key_code, window_data->mod_keys, false);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)insertText:(id)string replacementRange:(NSRange)replacementRange
{
kUnused(replacementRange);
if(window_data != 0x0) {
NSString *characters;
NSUInteger length;
if ([string isKindOfClass:[NSAttributedString class]])
characters = [string string];
else
characters = (NSString*) string;
length = [characters length];
for (NSUInteger i = 0; i < length; i++)
{
const unichar code = [characters characterAtIndex:i];
if ((code & 0xff00) == 0xf700)
continue;
kCall(char_input_func, code);
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)mainWindowChanged:(NSNotification *)notification
{
kUnused(notification);
if(window_data != 0x0) {
if(window_data->is_active == true) {
window_data->is_active = false;
kCall(active_func, false);
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setContentView:(NSView *)aView
{
if ([childContentView isEqualTo:aView]) {
return;
}
NSRect bounds = [self frame];
bounds.origin = NSZeroPoint;
OSXView *frameView = [super contentView];
if (!frameView)
{
frameView = [[[OSXView alloc] initWithFrame:bounds] autorelease];
[super setContentView:frameView];
}
if (childContentView)
{
[childContentView removeFromSuperview];
}
childContentView = aView;
[childContentView setFrame:[self contentRectForFrameRect:bounds]];
[childContentView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[frameView addSubview:childContentView];
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (NSView *)contentView
{
return childContentView;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (BOOL)canBecomeKeyWindow
{
return YES;
}
- (void)windowDidBecomeKey:(NSNotification *)notification
{
kUnused(notification);
if(window_data != 0x0) {
window_data->is_active = true;
kCall(active_func, true);
}
}
- (void)windowDidResignKey:(NSNotification *)notification
{
kUnused(notification);
if(window_data) {
window_data->is_active = false;
kCall(active_func, false);
}
}
- (void)windowWillClose:(NSNotification *)notification {
kUnused(notification);
if(window_data) {
window_data->close = true;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (BOOL)canBecomeMainWindow
{
return YES;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (NSRect)contentRectForFrameRect:(NSRect)windowFrame
{
windowFrame.origin = NSZeroPoint;
return NSInsetRect(windowFrame, 0, 0);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ (NSRect)frameRectForContentRect:(NSRect)windowContentRect styleMask:(NSWindowStyleMask)windowStyle
{
kUnused(windowStyle);
return NSInsetRect(windowContentRect, 0, 0);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)willClose
{
if(window_data != 0x0) {
window_data->close = true;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)windowDidResize:(NSNotification *)notification {
kUnused(notification);
if(window_data != 0x0) {
CGSize size = [self contentRectForFrameRect:[self frame]].size;
window_data->window_width = size.width;
window_data->window_height = size.height;
kCall(resize_func, size.width, size.height);
}
}
@end