/ include / AppKit / NSApplication.hpp
NSApplication.hpp
  1  /*
  2   *
  3   * Copyright 2020-2021 Apple Inc.
  4   *
  5   * Licensed under the Apache License, Version 2.0 (the "License");
  6   * you may not use this file except in compliance with the License.
  7   * You may obtain a copy of the License at
  8   *
  9   *     http://www.apache.org/licenses/LICENSE-2.0
 10   *
 11   * Unless required by applicable law or agreed to in writing, software
 12   * distributed under the License is distributed on an "AS IS" BASIS,
 13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14   * See the License for the specific language governing permissions and
 15   * limitations under the License.
 16   */
 17  
 18  
 19  //-------------------------------------------------------------------------------------------------------------------------------------------------------------
 20  //
 21  // AppKit/NSApplication.hpp
 22  //
 23  //-------------------------------------------------------------------------------------------------------------------------------------------------------------
 24  
 25  #pragma once
 26  
 27  //-------------------------------------------------------------------------------------------------------------------------------------------------------------
 28  
 29  #include <Foundation/Foundation.hpp>
 30  #include "AppKitPrivate.hpp"
 31  
 32  namespace NS
 33  {
 34  	_NS_OPTIONS( NS::UInteger, WindowStyleMask )
 35  	{
 36  		WindowStyleMaskBorderless	   = 0,
 37  		WindowStyleMaskTitled		   = ( 1 << 0 ),
 38  		WindowStyleMaskClosable		 = ( 1 << 1 ),
 39  		WindowStyleMaskMiniaturizable   = ( 1 << 2 ),
 40  		WindowStyleMaskResizable		= ( 1 << 3 ),
 41  		WindowStyleMaskTexturedBackground = ( 1 << 8 ),
 42  		WindowStyleMaskUnifiedTitleAndToolbar = ( 1 << 12 ),
 43  		WindowStyleMaskFullScreen	   = ( 1 << 14 ),
 44  		WindowStyleMaskFullSizeContentView = ( 1 << 15 ),
 45  		WindowStyleMaskUtilityWindow	= ( 1 << 4 ),
 46  		WindowStyleMaskDocModalWindow   = ( 1 << 6 ),
 47  		WindowStyleMaskNonactivatingPanel   = ( 1 << 7 ),
 48  		WindowStyleMaskHUDWindow		= ( 1 << 13 )
 49  	};
 50  
 51  	_NS_ENUM( NS::UInteger, BackingStoreType )
 52  	{
 53  		BackingStoreRetained = 0,
 54  		BackingStoreNonretained = 1,
 55  		BackingStoreBuffered = 2
 56  	};
 57  
 58  	_NS_ENUM( NS::UInteger, ActivationPolicy )
 59  	{
 60  		ActivationPolicyRegular,
 61  		ActivationPolicyAccessory,
 62  		ActivationPolicyProhibited
 63  	};
 64  
 65  	class ApplicationDelegate
 66  	{
 67  		public:
 68  			virtual					~ApplicationDelegate() { }
 69  			virtual void			applicationWillFinishLaunching( Notification* pNotification ) { }
 70  			virtual void			applicationDidFinishLaunching( Notification* pNotification ) { }
 71  			virtual bool			applicationShouldTerminateAfterLastWindowClosed( class Application* pSender ) { return false; }
 72  	};
 73  
 74  	class Application : public NS::Referencing< Application >
 75  	{
 76  		public:
 77  			static Application*		sharedApplication();
 78  
 79  			void 					setDelegate( const ApplicationDelegate* pDelegate );
 80  
 81  			bool					setActivationPolicy( ActivationPolicy activationPolicy );
 82  
 83  			void					activateIgnoringOtherApps( bool ignoreOtherApps );
 84  
 85  			void					setMainMenu( const class Menu* pMenu );
 86  
 87  			NS::Array*				windows() const;
 88  
 89  			void					run();
 90  
 91  			void					terminate( const Object* pSender );
 92  	};
 93  
 94  }
 95  
 96  _NS_INLINE NS::Application* NS::Application::sharedApplication()
 97  {
 98  	return Object::sendMessage< Application* >( _APPKIT_PRIVATE_CLS( NSApplication ), _APPKIT_PRIVATE_SEL( sharedApplication ) );
 99  }
100  
101  _NS_INLINE void NS::Application::setDelegate( const ApplicationDelegate* pAppDelegate )
102  {
103  	// TODO: Use a more suitable Object instead of NS::Value?
104  	// NOTE: this pWrapper is only held with a weak reference
105  	NS::Value* pWrapper = NS::Value::value( pAppDelegate );
106  
107  	typedef void (*DispatchFunction)( NS::Value*, SEL, void* );
108  	
109  	DispatchFunction willFinishLaunching = []( Value* pSelf, SEL, void* pNotification ){
110  		auto pDel = reinterpret_cast< NS::ApplicationDelegate* >( pSelf->pointerValue() );
111  		pDel->applicationWillFinishLaunching( (NS::Notification *)pNotification );
112  	};
113  
114  	DispatchFunction didFinishLaunching = []( Value* pSelf, SEL, void* pNotification ){
115  		auto pDel = reinterpret_cast< NS::ApplicationDelegate* >( pSelf->pointerValue() );
116  		pDel->applicationDidFinishLaunching( (NS::Notification *)pNotification );
117  	};
118  
119  	DispatchFunction shouldTerminateAfterLastWindowClosed = []( Value* pSelf, SEL, void* pApplication ){
120  		auto pDel = reinterpret_cast< NS::ApplicationDelegate* >( pSelf->pointerValue() );
121  		pDel->applicationShouldTerminateAfterLastWindowClosed( (NS::Application *)pApplication );
122  	};
123  
124  	class_addMethod( (Class)_NS_PRIVATE_CLS( NSValue ), _APPKIT_PRIVATE_SEL( applicationWillFinishLaunching_ ), (IMP)willFinishLaunching, "v@:@" );
125  	class_addMethod( (Class)_NS_PRIVATE_CLS( NSValue ), _APPKIT_PRIVATE_SEL( applicationDidFinishLaunching_ ), (IMP)didFinishLaunching, "v@:@" );
126  	class_addMethod( (Class)_NS_PRIVATE_CLS( NSValue ), _APPKIT_PRIVATE_SEL( applicationShouldTerminateAfterLastWindowClosed_), (IMP)shouldTerminateAfterLastWindowClosed, "B@:@" );
127  
128  	Object::sendMessage< void >( this, _APPKIT_PRIVATE_SEL( setDelegate_ ), pWrapper );
129  }
130  
131  _NS_INLINE bool NS::Application::setActivationPolicy( ActivationPolicy activationPolicy )
132  {
133  	return NS::Object::sendMessage< bool >( this, _APPKIT_PRIVATE_SEL( setActivationPolicy_ ), activationPolicy );
134  }
135  
136  _NS_INLINE void NS::Application::activateIgnoringOtherApps( bool ignoreOtherApps )
137  {
138  	Object::sendMessage< void >( this, _APPKIT_PRIVATE_SEL( activateIgnoringOtherApps_ ), (ignoreOtherApps ? YES : NO) );
139  }
140  
141  _NS_INLINE void NS::Application::setMainMenu( const class Menu* pMenu )
142  {
143  	Object::sendMessage< void >( this, _APPKIT_PRIVATE_SEL( setMainMenu_ ), pMenu );
144  }
145  
146  _NS_INLINE NS::Array* NS::Application::windows() const
147  {
148  	return Object::sendMessage< NS::Array* >( this, _APPKIT_PRIVATE_SEL( windows ) );
149  }
150  
151  _NS_INLINE void NS::Application::run()
152  {
153  	Object::sendMessage< void >( this, _APPKIT_PRIVATE_SEL( run ) );
154  }
155  
156  _NS_INLINE void NS::Application::terminate( const Object* pSender )
157  {
158  	Object::sendMessage< void >( this, _APPKIT_PRIVATE_SEL( terminate_ ), pSender );
159  }