OpenRCT2/src/openrct2-ui/UiContext.macOS.mm

188 lines
6.4 KiB
Plaintext

#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#if defined(__APPLE__) && defined(__MACH__)
#import <Cocoa/Cocoa.h>
#include <mach-o/dyld.h>
#include <dlfcn.h>
#include <openrct2/common.h>
#include <openrct2/core/String.hpp>
#include <openrct2/ui/UiContext.h>
#include "UiContext.h"
#include <SDL.h>
namespace OpenRCT2 { namespace Ui
{
class macOSContext final : public IPlatformUiContext
{
private:
public:
macOSContext()
{
@autoreleasepool {
if ([NSWindow respondsToSelector:@selector(setAllowsAutomaticWindowTabbing:)]) {
[NSWindow setAllowsAutomaticWindowTabbing:NO];
}
}
}
void SetWindowIcon(SDL_Window * window) override
{
}
bool IsSteamOverlayAttached() override
{
STUB();
return false;
}
void ShowMessageBox(SDL_Window * window, const std::string &message) override
{
@autoreleasepool
{
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert addButtonWithTitle:@"OK"];
alert.messageText = [NSString stringWithUTF8String:message.c_str()];
[alert runModal];
}
}
std::string ShowFileDialog(SDL_Window * window, const FileDialogDesc &desc) override
{
@autoreleasepool
{
NSMutableArray *extensions = [NSMutableArray new];
for (const OpenRCT2::Ui::FileDialogDesc::Filter &filter: desc.Filters) {
if (filter.Pattern != "") {
NSString *fp = [NSString stringWithUTF8String:filter.Pattern.c_str()];
fp = [fp stringByReplacingOccurrencesOfString:@"*." withString:@""];
[extensions addObjectsFromArray:[fp componentsSeparatedByString:@";"]];
}
}
NSString *directory;
NSSavePanel *panel;
if (desc.Type == FILE_DIALOG_TYPE::SAVE)
{
NSString *filePath = [NSString stringWithUTF8String:desc.DefaultFilename.c_str()];
directory = filePath.stringByDeletingLastPathComponent;
NSString *basename = filePath.lastPathComponent;
panel = [NSSavePanel savePanel];
panel.nameFieldStringValue = [NSString stringWithFormat:@"%@.%@", basename, extensions.firstObject];
}
else if (desc.Type == FILE_DIALOG_TYPE::OPEN)
{
directory = [NSString stringWithUTF8String:desc.InitialDirectory.c_str()];
NSOpenPanel *open = [NSOpenPanel openPanel];
open.canChooseDirectories = false;
open.canChooseFiles = true;
open.allowsMultipleSelection = false;
panel = open;
} else {
return std::string();
}
panel.title = [NSString stringWithUTF8String:desc.Title.c_str()];
panel.allowedFileTypes = extensions;
panel.directoryURL = [NSURL fileURLWithPath:directory];
if ([panel runModal] == NSModalResponseCancel)
{
return std::string();
} else {
return panel.URL.path.UTF8String;
}
}
}
std::string ShowDirectoryDialog(SDL_Window * window, const std::string &title) override
{
@autoreleasepool
{
NSOpenPanel *panel = [NSOpenPanel openPanel];
panel.canChooseFiles = false;
panel.canChooseDirectories = true;
panel.allowsMultipleSelection = false;
if ([panel runModal] == NSModalResponseOK)
{
NSString *selectedPath = panel.URL.path;
const char *path = selectedPath.UTF8String;
return path;
} else {
return "";
}
}
}
private:
static sint32 Execute(const std::string &command, std::string * output = nullptr)
{
log_verbose("executing \"%s\"...\n", command.c_str());
FILE * fpipe = popen(command.c_str(), "r");
if (fpipe == nullptr)
{
return -1;
}
if (output != nullptr)
{
// Read output into buffer
std::vector<char> outputBuffer;
char buffer[1024];
size_t readBytes;
while ((readBytes = fread(buffer, 1, sizeof(buffer), fpipe)) > 0)
{
outputBuffer.insert(outputBuffer.begin(), buffer, buffer + readBytes);
}
// Trim line breaks
size_t outputLength = outputBuffer.size();
for (size_t i = outputLength - 1; i != SIZE_MAX; i--)
{
if (outputBuffer[i] == '\n')
{
outputLength = i;
}
else
{
break;
}
}
// Convert to string
*output = std::string(outputBuffer.data(), outputLength);
}
else
{
fflush(fpipe);
}
// Return exit code
return pclose(fpipe);
}
};
IPlatformUiContext * CreatePlatformUiContext()
{
return new macOSContext();
}
} }
#endif // __APPLE__ && __MACH__