1 module declui.backend; 2 3 import declui.components; 4 5 /** 6 The backend for a given UI toolkit. 7 It is used to create compoonents and to enter the main event loop. 8 */ 9 interface ToolkitBackend 10 { 11 /// Enters the main event loop for the backend. 12 void run(string[] args, IWindow window); 13 14 /// Creates a window. 15 IWindow window(); 16 17 /// Creates a label. 18 ILabel label(); 19 20 /// Creates a button. 21 IButton button(); 22 23 /// Creates a menubar. 24 IMenuBar menubar(); 25 26 /// Creates a menu. 27 IMenu menu(); 28 29 /// Creates a menu button. 30 IMenuButton menubutton(); 31 } 32 33 private static ToolkitBackend _backend = null; 34 35 /// Gets the backend used to create compoonents. 36 ToolkitBackend dui() 37 { 38 if (_backend is null) 39 { 40 _backend = createBackend(); 41 } 42 return _backend; 43 } 44 45 version(unittest) private ToolkitBackend createBackend() 46 { 47 import declui.testing : TestingBackend; 48 return new TestingBackend; 49 } 50 else private ToolkitBackend createBackend() 51 { 52 import std.process : environment; 53 import std.stdio : stderr; 54 import core.stdc.stdlib : exit; 55 56 auto toolkit = environment.get("DECLUI_TOOLKIT", "gtk"); 57 if (toolkit !in _toolkits) 58 { 59 stderr.writefln!"Error: there is no toolkit registered under the name '%s'."(toolkit); 60 stderr.writeln("The following toolkits are available:"); 61 foreach (name, _; _toolkits) 62 stderr.writefln!" - %s"(name); 63 exit(1); 64 } 65 66 return _toolkits[toolkit](); 67 } 68 69 alias ToolkitFactory = ToolkitBackend function(); 70 private ToolkitFactory[string] _toolkits; 71 72 /** 73 Registers a new toolkit backend that can be used to run the app. 74 Params: 75 factory = The factory that can create a toolkit backend. 76 name = The name of the backend. 77 */ 78 void registerToolkit(string name, ToolkitFactory factory) 79 { 80 _toolkits[name] = factory; 81 }