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 	/// Creates a text area.
41 	ITextArea textarea();
42 }
43 
44 private static ToolkitBackend _backend = null;
45 
46 /// Gets the backend used to create compoonents.
47 ToolkitBackend dui()
48 {
49 	if (_backend is null)
50 	{
51 		_backend = createBackend();
52 	}
53 	return _backend;
54 }
55 
56 version(unittest) private ToolkitBackend createBackend()
57 {
58 	import declui.testing : TestingBackend;
59 	return new TestingBackend;
60 }
61 else private ToolkitBackend createBackend()
62 {
63 	import std.process : environment;
64 	import std.stdio : stderr;
65 	import core.stdc.stdlib : exit;
66 
67 	auto toolkit = environment.get("DECLUI_TOOLKIT", "gtk");
68 	if (toolkit !in _toolkits)
69 	{
70 		stderr.writefln!"Error: there is no toolkit registered under the name '%s'."(toolkit);
71 		stderr.writeln("The following toolkits are available:");
72 		foreach (name, _; _toolkits)
73 			stderr.writefln!"  - %s"(name);
74 		exit(1);
75 	}
76 
77 	return _toolkits[toolkit]();
78 }
79 
80 alias ToolkitFactory = ToolkitBackend function();
81 private ToolkitFactory[string] _toolkits;
82 
83 /**
84 Registers a new toolkit backend that can be used to run the app.
85 Params:
86   factory = The factory that can create a toolkit backend.
87   name = The name of the backend.
88 */
89 void registerToolkit(string name, ToolkitFactory factory)
90 {
91 	_toolkits[name] = factory;
92 }