1 /*
2 These lines were written by an adorable little puppy sleeping on my keyboard.
3    /
4  oOO
5    \\_______/
6 	 \======\
7  	 ||    ||
8      ||    ||
9 
10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
11 2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222266
12 +36...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................-8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8
13 */
14 /**
15 Contains the core Component class.
16 This class will adapt itself at compile-time to a given DUI script.
17 */
18 module declui.core;
19 
20 import declui.components.component;
21 import declui.components.container;
22 import declui.backend;
23 import declui.parser;
24 
25 import std.traits;
26 import std.typecons;
27 import std.format;
28 import std.conv;
29 
30 private template symbolOfTag(Tag tag)
31 {
32 	alias symbolOfTag = __traits(getMember, dui().getWidgets(), tag.name);
33 }
34 
35 private template typeOfTag(Tag tag)
36 {
37 	alias typeOfTag = ReturnType!(symbolOfTag!tag);
38 }
39 
40 /**
41 This class will create a component from a Tag tree.
42 */
43 class ComponentFromTag(Tag tag) : ReturnType!(__traits(getMember, ToolkitWidgets, tag.name))
44 {
45 	/*
46 	These are all compile-time constructs that will automatically create the
47 	class according to the DUI file passed in as a type argument.
48 	*/
49 	alias Type = ReturnType!(__traits(getMember, ToolkitWidgets, tag.name));
50 
51 	private Type _instance;
52 
53 	private struct IdContainer
54 	{
55 		static foreach (tagged; tag.findIds)
56 		{
57 			mixin(format!`private %s _%s;`(
58 				fullyQualifiedName!(typeOfTag!tagged),
59 				tagged.id
60 			));
61 
62 			mixin(format!
63 				`private void %s(%s value)
64 				{
65 					_%s = value;
66 				}`(
67 				tagged.id,
68 				fullyQualifiedName!(typeOfTag!tagged),
69 				tagged.id
70 			));
71 
72 			mixin(format!
73 				`auto %s()
74 				{
75 					return _%s;
76 				}`(
77 				tagged.id,
78 				tagged.id
79 			));
80 		}
81 	}
82 
83 	/**
84 	A struct containing a reference to all children by their id.
85 	*/
86 	IdContainer byId;
87 
88     /**
89     Creates the component and all child components.
90     */
91 	this(EventHandler)(EventHandler eventHandler)
92 	{
93 		_instance = __traits(getMember, dui().getWidgets(), tag.name)();
94         static foreach (attribute; tag.attributes)
95         {
96 			static if (attribute.type == AttributeType..string)
97 				__traits(getMember, _instance, attribute.name)(attribute.value);
98 			else static if (attribute.type == AttributeType.boolean)
99 				__traits(getMember, _instance, attribute.name)(attribute.value.parse!bool);
100 			else static if (attribute.type == AttributeType.integer)
101 				__traits(getMember, _instance, attribute.name)(attribute.value.parse!int);
102 			else static if (attribute.type == AttributeType.callback)
103 				__traits(getMember, _instance, attribute.name)(&__traits(getMember, eventHandler, attribute.value));
104 			else
105 				static assert(0, "Unsupported type " ~ attribute.type);
106         }
107 
108         static if (tag.children.length > 0)
109         {
110 			static foreach (child; tag.children)
111 			{
112 				static assert(__traits(hasMember, ToolkitWidgets, child.name),
113 					"There is no tag with the name '" ~ child.name ~ "'");
114 				registerChild!(child)(new ComponentFromTag!(child)(eventHandler));
115 			}
116         }
117 	}
118 
119 	private void registerChild(Tag tag, C)(C component)
120 	{
121 		_instance.add(component);
122 		static if (tag.id.length > 0)
123 		{
124 			__traits(getMember, byId, tag.id) = component;
125 		}
126 	}
127 
128 	/*
129 	Auto-generated getters and setters.
130 	*/
131 	static foreach (memberName; __traits(allMembers, Type))
132 	{
133 		static foreach (member; __traits(getOverloads, Type, memberName))
134 		{
135 			static if (Parameters!member.length > 0)
136 			{
137 				mixin(`
138 					override %s %s(%s value)
139 					{
140 						return _instance.%s(value);
141 					}
142 					`.format(
143 						fullyQualifiedName!(ReturnType!member),
144 						memberName,
145 						fullyQualifiedName!(Parameters!member[0]),
146 						memberName)
147 				);
148 			}
149 			else
150 			{
151 				mixin(`
152 					override %s %s()
153 					{
154 						return _instance.%s();
155 					}
156 					`.format(
157 						fullyQualifiedName!(ReturnType!member),
158 						memberName,
159 						memberName)
160 				);
161 			}
162 		}
163 	}
164 }
165 
166 /**
167 This class will parse a DUI file and automatically create a user interface based
168 on that DUI file.
169 
170 Type Params:
171   file = The name of the DUI file. This file should be present in the views
172          directory and end with the `.dui` extension.
173 */
174 abstract class Component(string file) : ComponentFromTag!(parseDUI!file)
175 {
176 	private enum tag = parseDUI!file;
177 
178 	/// Instantiates a DUI file.
179 	this()
180 	{
181 		super(this);
182 	}
183 
184 	static foreach (callback; tag.findCallbacks)
185 	{
186 		mixin(format!"abstract void %s();"(callback));
187 	}
188 }
189 
190 @("IContainer can have children")
191 unittest
192 {
193 	enum tag = Tag("window", "", [], [Tag("label")]); // @suppress(dscanner.suspicious.unused_variable)
194 	static struct EventHandler {}
195 	new ComponentFromTag!(tag)(EventHandler());
196 }
197 
198 @("Non-IContainers cannot have children")
199 unittest
200 {
201 	enum tag = Tag("label", "", [], [Tag("label")]); // @suppress(dscanner.suspicious.unused_variable)
202 	static struct EventHandler {}
203 	assert(!__traits(compiles, new ComponentFromTag!tag(EventHandler())), "Did compile Component, but shouldn't have");
204 }