Files
renderdoc/util/test/demos/apple/apple_window.cpp
T
Jake Turner 9b457ed91d Add void *layer to Demos AppleWindow
layer is required for "VK_EXT_metal_surface"
2026-02-09 20:06:59 +00:00

195 lines
6.4 KiB
C++

/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2022-2026 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "apple_window.h"
#include "official/metal-cpp.h"
static NS::Application *pSharedApplication = NULL;
MyAppDelegate *AppleWindow::pAppDelegate = NULL;
class MyAppDelegate : public NS::ApplicationDelegate
{
public:
~MyAppDelegate();
NS::Menu *createMenuBar();
virtual void applicationWillFinishLaunching(NS::Notification *pNotification) override;
virtual void applicationDidFinishLaunching(NS::Notification *pNotification) override;
virtual bool applicationShouldTerminateAfterLastWindowClosed(NS::Application *pSender) override;
void CreateWindow(int width, int height, const char *title);
NS::View *GetContentView();
NS::Window *GetWindow();
private:
NS::Window *_pWindow;
};
MyAppDelegate::~MyAppDelegate()
{
_pWindow->release();
}
NS::Menu *MyAppDelegate::createMenuBar()
{
using NS::StringEncoding::UTF8StringEncoding;
NS::Menu *pMainMenu = NS::Menu::alloc()->init();
NS::MenuItem *pAppMenuItem = NS::MenuItem::alloc()->init();
NS::Menu *pAppMenu = NS::Menu::alloc()->init(NS::String::string("Appname", UTF8StringEncoding));
NS::String *appName = NS::RunningApplication::currentApplication()->localizedName();
NS::String *quitItemName =
NS::String::string("Quit ", UTF8StringEncoding)->stringByAppendingString(appName);
SEL quitCb =
NS::MenuItem::registerActionCallback("appQuit", [](void *, SEL, const NS::Object *pSender) {
NS::Application *pApp = NS::Application::sharedApplication();
pApp->terminate(pSender);
});
NS::MenuItem *pAppQuitItem =
pAppMenu->addItem(quitItemName, quitCb, NS::String::string("q", UTF8StringEncoding));
pAppQuitItem->setKeyEquivalentModifierMask(NS::EventModifierFlagCommand);
pAppMenuItem->setSubmenu(pAppMenu);
NS::MenuItem *pWindowMenuItem = NS::MenuItem::alloc()->init();
NS::Menu *pWindowMenu = NS::Menu::alloc()->init(NS::String::string("Window", UTF8StringEncoding));
SEL closeWindowCb =
NS::MenuItem::registerActionCallback("windowClose", [](void *, SEL, const NS::Object *) {
NS::Application *pApp = NS::Application::sharedApplication();
pApp->windows()->object<NS::Window>(0)->close();
});
NS::MenuItem *pCloseWindowItem =
pWindowMenu->addItem(NS::String::string("Close Window", UTF8StringEncoding), closeWindowCb,
NS::String::string("w", UTF8StringEncoding));
pCloseWindowItem->setKeyEquivalentModifierMask(NS::EventModifierFlagCommand);
pWindowMenuItem->setSubmenu(pWindowMenu);
pMainMenu->addItem(pAppMenuItem);
pMainMenu->addItem(pWindowMenuItem);
pAppMenuItem->release();
pWindowMenuItem->release();
pAppMenu->release();
pWindowMenu->release();
return pMainMenu->autorelease();
}
void MyAppDelegate::applicationWillFinishLaunching(NS::Notification *pNotification)
{
NS::Menu *pMenu = createMenuBar();
NS::Application *pApp = (NS::Application *)pNotification->object();
pApp->setMainMenu(pMenu);
pApp->setActivationPolicy(NS::ActivationPolicy::ActivationPolicyRegular);
}
void MyAppDelegate::applicationDidFinishLaunching(NS::Notification *pNotification)
{
NS::Application *pApp = (NS::Application *)pNotification->object();
pApp->activateIgnoringOtherApps(true);
}
bool MyAppDelegate::applicationShouldTerminateAfterLastWindowClosed(NS::Application *pSender)
{
return true;
}
void MyAppDelegate::CreateWindow(int width, int height, const char *title)
{
CGRect frame = CGRectMake(100.0f, 100.0f, width, height);
_pWindow = NS::Window::alloc()->init(frame, NS::WindowStyleMaskClosable | NS::WindowStyleMaskTitled,
NS::BackingStoreBuffered, false);
NS::View *view = _pWindow->contentView();
view->setWantsLayer(true);
view->setLayer((CA::Layer *)CA::MetalLayer::layer());
_pWindow->setTitle(NS::String::string(title, NS::StringEncoding::UTF8StringEncoding));
_pWindow->makeKeyAndOrderFront(NULL);
}
NS::View *MyAppDelegate::GetContentView()
{
return _pWindow->contentView();
}
NS::Window *MyAppDelegate::GetWindow()
{
return _pWindow;
}
AppleWindow::~AppleWindow()
{
pAppDelegate = NULL;
}
AppleWindow::AppleWindow(int width, int height, const char *title) : GraphicsWindow(title)
{
pAppDelegate->CreateWindow(width, height, title);
NS::View *nsView = pAppDelegate->GetContentView();
view = nsView;
layer = nsView->layer();
}
bool AppleWindow::Init()
{
pSharedApplication = NS::Application::sharedApplication();
pAppDelegate = new MyAppDelegate();
pSharedApplication->setDelegate(pAppDelegate);
if(!NS::RunningApplication::currentApplication()->finishedLaunching())
pSharedApplication->finishLaunching();
return true;
}
void AppleWindow::Resize(int width, int height)
{
TEST_ERROR("Resize is not implemented");
}
extern "C" void *const NSDefaultRunLoopMode;
bool AppleWindow::Update()
{
NS::AutoreleasePool *pAutoreleasePool = NS::AutoreleasePool::alloc()->init();
while(true)
{
NS::Event *event = pSharedApplication->nextEventMatchingMask(
(int)NS::EventMaskAny, NS::Date::distantPast(), (NS::String *)NSDefaultRunLoopMode, true);
if(event == NULL)
break;
pSharedApplication->sendEvent(event);
}
pAutoreleasePool->release();
return pAppDelegate->GetWindow()->visible();
}