ApplicationWindowMacOS.mm 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2024 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include <TestFramework.h>
  5. #include <Window/ApplicationWindowMacOS.h>
  6. #import <MetalKit/MetalKit.h>
  7. // This class implements a metal view
  8. @interface MetalView : MTKView <MTKViewDelegate>
  9. @end
  10. @implementation MetalView
  11. {
  12. ApplicationWindowMacOS *mWindow;
  13. }
  14. - (MetalView *)init:(ApplicationWindowMacOS *)window
  15. {
  16. id<MTLDevice> device = MTLCreateSystemDefaultDevice();
  17. self = [super initWithFrame: NSMakeRect(0, 0, window->GetWindowWidth(), window->GetWindowHeight()) device: device];
  18. [device release];
  19. mWindow = window;
  20. self.delegate = self;
  21. return self;
  22. }
  23. - (BOOL)acceptsFirstResponder
  24. {
  25. return YES;
  26. }
  27. - (BOOL)canBecomeKeyView
  28. {
  29. return YES;
  30. }
  31. - (BOOL)isFlipped
  32. {
  33. return YES;
  34. }
  35. - (void)mouseMoved:(NSEvent *)event
  36. {
  37. NSPoint location_in_view = [self convertPoint: event.locationInWindow fromView: nil];
  38. NSPoint location_in_backing = [self convertPointToBacking: location_in_view];
  39. mWindow->OnMouseMoved(location_in_backing.x, -location_in_backing.y);
  40. }
  41. - (void)drawInMTKView:(MTKView *)view
  42. {
  43. @autoreleasepool
  44. {
  45. mWindow->RenderCallback();
  46. }
  47. }
  48. - (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size
  49. {
  50. mWindow->OnWindowResized(size.width, size.height);
  51. }
  52. @end
  53. // This is the main application delegate that tells us if we're starting / stopping
  54. @interface AppDelegate : NSObject <NSApplicationDelegate>
  55. @end
  56. @implementation AppDelegate
  57. -(void)applicationDidFinishLaunching:(NSNotification *)notification
  58. {
  59. // Add the Quit button to the first menu item on the toolbar
  60. NSMenu *app_menu = [[NSApp mainMenu] itemAtIndex: 0].submenu;
  61. NSMenuItem *quit_item = [[NSMenuItem alloc] initWithTitle: @"Quit" action: @selector(terminate:) keyEquivalent: @"q"];
  62. [app_menu addItem: quit_item];
  63. }
  64. -(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
  65. {
  66. // Close the app when the window is closed
  67. return YES;
  68. }
  69. @end
  70. ApplicationWindowMacOS::~ApplicationWindowMacOS()
  71. {
  72. [mMetalView release];
  73. }
  74. void ApplicationWindowMacOS::Initialize(const char *inTitle)
  75. {
  76. // Create metal view
  77. MetalView *view = [[MetalView alloc] init: this];
  78. view.clearColor = MTLClearColorMake(0.098f, 0.098f, 0.439f, 1.000f);
  79. view.depthStencilPixelFormat = MTLPixelFormatDepth32Float;
  80. view.clearDepth = 0.0f;
  81. mMetalView = view;
  82. // Create window
  83. NSWindow *window = [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, mWindowWidth, mWindowHeight)
  84. styleMask: NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable
  85. backing: NSBackingStoreBuffered
  86. defer: NO];
  87. window.contentView = view;
  88. [window setAcceptsMouseMovedEvents: YES];
  89. [window setTitle: [NSString stringWithCString: inTitle encoding: NSUTF8StringEncoding]];
  90. [window makeKeyAndOrderFront: nil];
  91. }
  92. void ApplicationWindowMacOS::MainLoop(ApplicationWindow::RenderCallback inRenderCallback)
  93. {
  94. mRenderCallback = inRenderCallback;
  95. @autoreleasepool
  96. {
  97. NSApplication *app = [NSApplication sharedApplication];
  98. AppDelegate *delegate = [[AppDelegate alloc] init];
  99. [app setDelegate: delegate];
  100. [app run];
  101. [delegate release];
  102. }
  103. }
  104. CAMetalLayer *ApplicationWindowMacOS::GetMetalLayer() const
  105. {
  106. return (CAMetalLayer *)mMetalView.layer;
  107. }