1 /** 2 * ae.ui.app.application 3 * 4 * License: 5 * This Source Code Form is subject to the terms of 6 * the Mozilla Public License, v. 2.0. If a copy of 7 * the MPL was not distributed with this file, You 8 * can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * Authors: 11 * Vladimir Panteleev <ae@cy.md> 12 */ 13 14 module ae.ui.app.application; 15 16 import ae.sys.desktop; 17 import ae.sys.config; 18 import ae.ui.shell.shell; 19 import ae.ui.shell.events; 20 import ae.ui.video.renderer; 21 22 /// The purpose of this class is to allow the application to provide app-specific information to the framework. 23 // This class could theoretically be split up into more layers (ShellApplication, etc.) 24 class Application 25 { 26 Config config; /// 27 28 this() 29 { 30 config = new Config(getName(), getCompanyName()); 31 } /// 32 33 // ************************** Application information ************************** 34 35 /// Returns a string containing the application name, as visible in the window caption and taskbar, and used in filesystem/registry paths. 36 abstract string getName(); 37 38 /// Returns the company name (used for Windows registry paths). 39 abstract string getCompanyName(); 40 41 // TODO: getIcon 42 43 // ******************************** Entry point ******************************** 44 45 /// The application "main" function. The application can create a shell here. 46 abstract int run(string[] args); 47 48 // ************************** Default screen settings ************************** 49 50 ShellSettings getDefaultShellSettings() 51 { 52 ShellSettings settings; 53 static if (is(typeof(getDesktopResolution))) 54 getDesktopResolution(settings.fullScreenX, settings.fullScreenY); 55 return settings; 56 } /// 57 58 /// Override these to customize application properties and requirements. 59 ShellSettings getShellSettings() { return config.read("ShellSettings", getDefaultShellSettings()); } 60 void setShellSettings(ShellSettings settings) { config.write("ShellSettings", settings); } /// ditto 61 62 bool isResizable() { return true; } /// ditto 63 bool needSound() { return false; } /// ditto 64 bool needJoystick() { return false; } /// ditto 65 66 // ****************************** Event handlers ******************************* 67 68 //void handleMouseEnter() {} 69 //void handleMouseLeave() {} 70 //void handleKeyboardFocus() {} 71 //void handleKeyboardBlur() {} 72 //void handleMinimize() {} 73 //void handleRestore() {} 74 75 /// Called after video initialization. 76 /// Video initialization currently also happens when the window is resized. 77 /// The window size can be accessed via shell.video.getScreenSize. 78 void handleInit() {} 79 80 /// Override these to handle input. 81 void handleKeyDown(Key key/*, modifiers? */, dchar character) {} /// ditto 82 void handleKeyUp(Key key/*, modifiers? */) {} /// ditto 83 84 void handleMouseDown(uint x, uint y, MouseButton button) {} /// ditto 85 void handleMouseUp(uint x, uint y, MouseButton button) {} /// ditto 86 void handleMouseMove(uint x, uint y, MouseButtons buttons) {} /// ditto 87 //void handleMouseRelMove(int dx, int dy) {} /// when cursor is clipped 88 89 void handleJoyAxisMotion(int axis, short value) {} /// ditto 90 void handleJoyHatMotion (int hat, JoystickHatState state) {} /// ditto 91 void handleJoyButtonDown(int button) {} /// ditto 92 void handleJoyButtonUp (int button) {} /// ditto 93 94 //void handleResize(uint w, uint h) {} 95 void handleQuit() {} /// ditto 96 97 // ********************************* Rendering ********************************* 98 99 void render(Renderer r) {} /// Override to implement rendering. 100 } 101 102 private __gshared Application application; 103 104 /// The application must call this function with its own Application implementation in a static constructor. 105 void createApplication(A : Application)() 106 { 107 assert(application is null, "Application already set"); 108 application = new A; 109 } 110 111 // for use in ae.ui.app.* 112 int runApplication(string[] args) 113 { 114 assert(application !is null, "Application object not set"); 115 return application.run(args); 116 } /// 117 118 /// Wraps a delegate that is to be called only from the application thread context. 119 struct AppCallbackEx(A...) 120 { 121 private void delegate(A) f; 122 123 void bind(void delegate(A) f) 124 { 125 this.f = f; 126 } /// 127 128 /// Blocks. 129 void call(A args) 130 { 131 assert(f, "Attempting to call unbound AppCallback"); 132 synchronized(application) 133 { 134 f(args); 135 } 136 } 137 138 bool opCast(T)() 139 if (is(T == bool)) 140 { 141 return f !is null; 142 } /// 143 } 144 145 alias AppCallbackEx!() AppCallback; ///