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