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 <vladimir@thecybershadow.net> 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 ShellSettings getShellSettings() { return config.read("ShellSettings", getDefaultShellSettings()); } 59 void setShellSettings(ShellSettings settings) { config.write("ShellSettings", settings); } 60 61 bool isResizable() { return true; } 62 bool needSound() { return false; } 63 bool needJoystick() { return false; } 64 65 // ****************************** Event handlers ******************************* 66 67 //void handleMouseEnter() {} 68 //void handleMouseLeave() {} 69 //void handleKeyboardFocus() {} 70 //void handleKeyboardBlur() {} 71 //void handleMinimize() {} 72 //void handleRestore() {} 73 74 /// Called after video initialization. 75 /// Video initialization currently also happens when the window is resized. 76 /// The window size can be accessed via shell.video.getScreenSize. 77 void handleInit() {} 78 79 void handleKeyDown(Key key/*, modifiers? */, dchar character) {} 80 void handleKeyUp(Key key/*, modifiers? */) {} 81 82 void handleMouseDown(uint x, uint y, MouseButton button) {} 83 void handleMouseUp(uint x, uint y, MouseButton button) {} 84 void handleMouseMove(uint x, uint y, MouseButtons buttons) {} 85 //void handleMouseRelMove(int dx, int dy) {} /// when cursor is clipped 86 87 void handleJoyAxisMotion(int axis, short value) {} 88 void handleJoyHatMotion (int hat, JoystickHatState state) {} 89 void handleJoyButtonDown(int button) {} 90 void handleJoyButtonUp (int button) {} 91 92 //void handleResize(uint w, uint h) {} 93 void handleQuit() {} 94 95 // ********************************* Rendering ********************************* 96 97 void render(Renderer r) {} 98 } 99 100 private __gshared Application application; 101 102 /// The application must call this function with its own Application implementation in a static constructor. 103 void createApplication(A : Application)() 104 { 105 assert(application is null, "Application already set"); 106 application = new A; 107 } 108 109 // for use in ae.ui.app.* 110 int runApplication(string[] args) 111 { 112 assert(application !is null, "Application object not set"); 113 return application.run(args); 114 } 115 116 /// Wraps a delegate that is to be called only from the application thread context. 117 struct AppCallbackEx(A...) 118 { 119 private void delegate(A) f; 120 121 void bind(void delegate(A) f) 122 { 123 this.f = f; 124 } 125 126 /// Blocks. 127 void call(A args) 128 { 129 assert(f, "Attempting to call unbound AppCallback"); 130 synchronized(application) 131 { 132 f(args); 133 } 134 } 135 136 bool opCast(T)() 137 if (is(T == bool)) 138 { 139 return f !is null; 140 } 141 } 142 143 alias AppCallbackEx!() AppCallback;