1/* 2 * Copyright 2019-2019 Attila Kocsis. All rights reserved. 3 * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause 4 */ 5 6#include "entry_p.h" 7#if BX_PLATFORM_OSX 8 9#include <bx/allocator.h> 10#include <bx/filepath.h> 11#include <bx/string.h> 12#include <bx/readerwriter.h> 13#include <bx/process.h> 14#include <bx/semaphore.h> 15 16#import <AppKit/AppKit.h> 17 18#include "dialog.h" 19 20class Split 21{ 22public: 23 Split(const bx::StringView& _str, char _ch) 24 : m_str(_str) 25 , m_token(_str.getPtr(), bx::strFind(_str, _ch).getPtr() ) 26 , m_ch(_ch) 27 { 28 } 29 30 bx::StringView next() 31 { 32 bx::StringView result = m_token; 33 m_token = bx::strTrim( 34 bx::StringView(m_token.getTerm()+1 35 , bx::strFind(bx::StringView(m_token.getTerm()+1, m_str.getTerm() ), m_ch).getPtr() ) 36 , " \t\n" 37 ); 38 return result; 39 } 40 41 bool isDone() const 42 { 43 return m_token.isEmpty(); 44 } 45 46private: 47 const bx::StringView& m_str; 48 bx::StringView m_token; 49 char m_ch; 50}; 51 52 53bool openFileSelectionDialog( 54 bx::FilePath& _inOutFilePath 55 , FileSelectionDialogType::Enum _type 56 , const bx::StringView& _title 57 , const bx::StringView& _filter 58 ) 59{ 60 NSMutableArray* fileTypes = [NSMutableArray arrayWithCapacity:10]; 61 bx::Error err; 62 63 for (bx::LineReader lr(_filter); !lr.isDone() && err.isOk();) 64 { 65 const bx::StringView line = lr.next(); 66 const bx::StringView sep = bx::strFind(line, '|'); 67 68 if (!sep.isEmpty() ) 69 { 70 for (Split split(bx::strTrim(bx::StringView(sep.getPtr()+1, line.getTerm() ), " "), ' '); !split.isDone() && err.isOk();) 71 { 72 const bx::StringView token = split.next(); 73 74 if ( token.getLength() >= 3 && token.getPtr()[0] == '*' 75 && token.getPtr()[1] == '.' && bx::isAlphaNum(token.getPtr()[2]) ) 76 { 77 NSString* extension = [[NSString alloc] initWithBytes:token.getPtr()+2 length:token.getLength()-2 encoding:NSASCIIStringEncoding]; 78 [fileTypes addObject: extension]; 79 } 80 } 81 } 82 } 83 84 __block NSString* fileName = nil; 85 bx::Semaphore semaphore; 86 bx::Semaphore* psemaphore = &semaphore; 87 88 CFRunLoopPerformBlock([[NSRunLoop mainRunLoop] getCFRunLoop], 89 kCFRunLoopCommonModes, 90 ^{ 91 NSSavePanel* panel = nil; 92 93 if ( FileSelectionDialogType::Open == _type) 94 { 95 NSOpenPanel* openPanel = [NSOpenPanel openPanel]; 96 openPanel.canChooseFiles = TRUE; 97 openPanel.allowsMultipleSelection = FALSE; 98 openPanel.canChooseDirectories = FALSE; 99 panel = openPanel; 100 } 101 else 102 { 103 panel = [NSSavePanel savePanel]; 104 } 105 106 panel.message = [[NSString alloc] initWithBytes:_title.getPtr() length:_title.getLength() encoding:NSASCIIStringEncoding]; 107 panel.directoryURL = [NSURL URLWithString:@(_inOutFilePath.getCPtr())]; 108 panel.allowedFileTypes = fileTypes; 109 110 if ([panel runModal] == NSModalResponseOK) 111 { 112 NSURL* url = [panel URL]; 113 if (nil != url) 114 { 115 fileName = [url path]; 116 [fileName retain]; 117 } 118 } 119 [panel close]; 120 psemaphore->post(); 121 }); 122 123 semaphore.wait(); 124 125 if ( fileName != nil ) 126 { 127 _inOutFilePath.set([fileName UTF8String]); 128 [fileName release]; 129 return true; 130 } 131 132 return false; 133} 134 135#endif 136