ApplicationWindowMacOS.mm 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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. [super initWithFrame: NSMakeRect(0, 0, window->GetWindowWidth(), window->GetWindowHeight()) device: MTLCreateSystemDefaultDevice()];
  17. mWindow = window;
  18. self.delegate = self;
  19. return self;
  20. }
  21. - (bool)acceptsFirstResponder
  22. {
  23. return YES;
  24. }
  25. - (bool)canBecomeKeyView
  26. {
  27. return YES;
  28. }
  29. - (void)mouseMoved:(NSEvent *)event
  30. {
  31. NSPoint location = [event locationInWindow];
  32. mWindow->OnMouseMoved(location.x, mWindow->GetWindowHeight() - location.y);
  33. }
  34. - (void)drawInMTKView:(MTKView *)view
  35. {
  36. mWindow->RenderCallback();
  37. }
  38. - (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size
  39. {
  40. mWindow->OnWindowResized(size.width, size.height);
  41. }
  42. @end
  43. // This is the main application delegate that tells us if we're starting / stopping
  44. @interface AppDelegate : NSObject <NSApplicationDelegate>
  45. @end
  46. @implementation AppDelegate
  47. -(void)applicationDidFinishLaunching:(NSNotification *)notification
  48. {
  49. // Add the Quit button to the first menu item on the toolbar
  50. NSMenu *app_menu = [[NSApp mainMenu] itemAtIndex: 0].submenu;
  51. NSMenuItem *quit_item = [[NSMenuItem alloc] initWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"];
  52. [app_menu addItem:quit_item];
  53. }
  54. -(bool)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
  55. {
  56. // Close the app when the window is closed
  57. return YES;
  58. }
  59. @end
  60. void ApplicationWindowMacOS::Initialize()
  61. {
  62. // Create metal view
  63. MetalView *view = [[MetalView alloc] init: this];
  64. mMetalLayer = (CAMetalLayer *)view.layer;
  65. // Create window
  66. NSWindow *window = [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, mWindowWidth, mWindowHeight)
  67. styleMask: NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable
  68. backing: NSBackingStoreBuffered
  69. defer: NO];
  70. window.contentView = view;
  71. [window setAcceptsMouseMovedEvents: YES];
  72. [window setTitle: @"TestFramework"];
  73. [window makeKeyAndOrderFront: nil];
  74. }
  75. void ApplicationWindowMacOS::MainLoop(ApplicationWindow::RenderCallback inRenderCallback)
  76. {
  77. mRenderCallback = inRenderCallback;
  78. @autoreleasepool
  79. {
  80. NSApplication *app = [NSApplication sharedApplication];
  81. AppDelegate *delegate = [[AppDelegate alloc] init];
  82. [app setDelegate:delegate];
  83. [app run];
  84. }
  85. }