gioui.org/ui@v0.0.0-20190926171558-ce74bc0cbaea/app/os_macos.m (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  // +build darwin,!ios
     4  
     5  @import AppKit;
     6  
     7  #include "os_macos.h"
     8  #include "_cgo_export.h"
     9  
    10  @interface GioDelegate : NSObject<NSApplicationDelegate, NSWindowDelegate>
    11  @property (strong,nonatomic) NSWindow *window;
    12  @end
    13  
    14  @implementation GioDelegate
    15  - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    16  	[[NSRunningApplication currentApplication] activateWithOptions:(NSApplicationActivateAllWindows | NSApplicationActivateIgnoringOtherApps)];
    17  	[self.window makeKeyAndOrderFront:self];
    18  	gio_onShow((__bridge CFTypeRef)self.window.contentView);
    19  }
    20  - (void)applicationDidHide:(NSNotification *)aNotification {
    21  	gio_onHide((__bridge CFTypeRef)self.window.contentView);
    22  }
    23  - (void)applicationWillUnhide:(NSNotification *)notification {
    24  	gio_onShow((__bridge CFTypeRef)self.window.contentView);
    25  }
    26  - (void)windowWillMiniaturize:(NSNotification *)notification {
    27  	gio_onHide((__bridge CFTypeRef)self.window.contentView);
    28  }
    29  - (void)windowDidDeminiaturize:(NSNotification *)notification {
    30  	gio_onShow((__bridge CFTypeRef)self.window.contentView);
    31  }
    32  - (void)windowDidChangeScreen:(NSNotification *)notification {
    33  	CGDirectDisplayID dispID = [[[self.window screen] deviceDescription][@"NSScreenNumber"] unsignedIntValue];
    34  	CFTypeRef view = (__bridge CFTypeRef)self.window.contentView;
    35  	gio_updateDisplayLink(view, dispID);
    36  }
    37  - (void)windowDidBecomeKey:(NSNotification *)notification {
    38  	gio_onFocus((__bridge CFTypeRef)self.window.contentView, YES);
    39  }
    40  - (void)windowDidResignKey:(NSNotification *)notification {
    41  	gio_onFocus((__bridge CFTypeRef)self.window.contentView, NO);
    42  }
    43  - (void)windowWillClose:(NSNotification *)notification {
    44  	gio_onTerminate((__bridge CFTypeRef)self.window.contentView);
    45  	self.window.delegate = nil;
    46  	[NSApp terminate:nil];
    47  }
    48  @end
    49  
    50  CGFloat gio_viewHeight(CFTypeRef viewRef) {
    51  	NSView *view = (__bridge NSView *)viewRef;
    52  	return [view bounds].size.height;
    53  }
    54  
    55  CGFloat gio_viewWidth(CFTypeRef viewRef) {
    56  	NSView *view = (__bridge NSView *)viewRef;
    57  	return [view bounds].size.width;
    58  }
    59  
    60  // Points pr. dp.
    61  static CGFloat getPointsPerDP(NSScreen *screen) {
    62  	NSDictionary *description = [screen deviceDescription];
    63  	NSSize displayPixelSize = [[description objectForKey:NSDeviceSize] sizeValue];
    64  	CGSize displayPhysicalSize = CGDisplayScreenSize([[description objectForKey:@"NSScreenNumber"] unsignedIntValue]);
    65  	return (25.4/160)*displayPixelSize.width / displayPhysicalSize.width;
    66  }
    67  
    68  // Pixels pr dp.
    69  CGFloat gio_getPixelsPerDP(void) {
    70  	NSScreen *screen = [NSScreen mainScreen];
    71  	return getPointsPerDP(screen);
    72  }
    73  
    74  CGFloat gio_getBackingScale() {
    75  	NSScreen *screen = [NSScreen mainScreen];
    76  	return [screen backingScaleFactor];
    77  }
    78  
    79  CGFloat gio_getViewBackingScale(CFTypeRef viewRef) {
    80  	NSView *view = (__bridge NSView *)viewRef;
    81  	return [view.window backingScaleFactor];
    82  }
    83  
    84  void gio_main(CFTypeRef viewRef, const char *title, CGFloat width, CGFloat height) {
    85  	@autoreleasepool {
    86  		NSView *view = (NSView *)CFBridgingRelease(viewRef);
    87  		[NSApplication sharedApplication];
    88  		[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
    89  
    90  		NSMenuItem *mainMenu = [NSMenuItem new];
    91  
    92  		NSMenu *menu = [NSMenu new];
    93  		NSMenuItem *hideMenuItem = [[NSMenuItem alloc] initWithTitle:@"Hide"
    94  															  action:@selector(hide:)
    95  													   keyEquivalent:@"h"];
    96  		[menu addItem:hideMenuItem];
    97  		NSMenuItem *quitMenuItem = [[NSMenuItem alloc] initWithTitle:@"Quit"
    98  															  action:@selector(terminate:)
    99  													   keyEquivalent:@"q"];
   100  		[menu addItem:quitMenuItem];
   101  		[mainMenu setSubmenu:menu];
   102  		NSMenu *menuBar = [NSMenu new];
   103  		[menuBar addItem:mainMenu];
   104  		[NSApp setMainMenu:menuBar];
   105  
   106  		NSRect rect = NSMakeRect(0, 0, width, height);
   107  		NSWindowStyleMask styleMask = NSWindowStyleMaskTitled |
   108  			NSWindowStyleMaskResizable |
   109  			NSWindowStyleMaskMiniaturizable |
   110  			NSWindowStyleMaskClosable;
   111  		NSWindow* window = [[NSWindow alloc] initWithContentRect:rect
   112  													   styleMask:styleMask
   113  														 backing:NSBackingStoreBuffered
   114  														   defer:NO];
   115  		window.title = [NSString stringWithUTF8String: title];
   116  		[window cascadeTopLeftFromPoint:NSMakePoint(20,20)];
   117  		[window setAcceptsMouseMovedEvents:YES];
   118  
   119  		gio_onCreate((__bridge CFTypeRef)view);
   120  		GioDelegate *del = [[GioDelegate alloc] init];
   121  		del.window = window;
   122  		[window setDelegate:del];
   123  		[NSApp setDelegate:del];
   124  		[window setContentView:view];
   125  		[window makeFirstResponder:view];
   126  
   127  
   128  		[NSApp run];
   129  	}
   130  }