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, 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, ToolkitBackend, 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, dui(), 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, 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 registerChild!(child)(new ComponentFromTag!(child)(eventHandler)); 113 } 114 } 115 } 116 117 private void registerChild(Tag tag, C)(C component) 118 { 119 _instance.add(component); 120 static if (tag.id.length > 0) 121 { 122 __traits(getMember, byId, tag.id) = component; 123 } 124 } 125 126 /* 127 Auto-generated getters and setters. 128 */ 129 static foreach (memberName; __traits(allMembers, Type)) 130 { 131 static foreach (member; __traits(getOverloads, Type, memberName)) 132 { 133 static if (Parameters!member.length > 0) 134 { 135 mixin(` 136 override %s %s(%s value) 137 { 138 return _instance.%s(value); 139 } 140 `.format( 141 fullyQualifiedName!(ReturnType!member), 142 memberName, 143 fullyQualifiedName!(Parameters!member[0]), 144 memberName) 145 ); 146 } 147 else 148 { 149 mixin(` 150 override %s %s() 151 { 152 return _instance.%s(); 153 } 154 `.format( 155 fullyQualifiedName!(ReturnType!member), 156 memberName, 157 memberName) 158 ); 159 } 160 } 161 } 162 } 163 164 /** 165 This class will parse a DUI file and automatically create a user interface based 166 on that DUI file. 167 168 Type Params: 169 file = The name of the DUI file. This file should be present in the views 170 directory and end with the `.dui` extension. 171 */ 172 abstract class Component(string file) : ComponentFromTag!(parseDUI!file) 173 { 174 private enum tag = parseDUI!file; 175 176 /// Instantiates a DUI file. 177 this() 178 { 179 super(this); 180 } 181 182 static foreach (callback; tag.findCallbacks) 183 { 184 mixin(format!"abstract void %s();"(callback)); 185 } 186 } 187 188 @("IContainer can have children") 189 unittest 190 { 191 enum tag = Tag("window", "", [], [Tag("label")]); // @suppress(dscanner.suspicious.unused_variable) 192 static struct EventHandler {} 193 new ComponentFromTag!(tag)(EventHandler()); 194 } 195 196 @("Non-IContainers cannot have children") 197 unittest 198 { 199 enum tag = Tag("label", "", [], [Tag("label")]); // @suppress(dscanner.suspicious.unused_variable) 200 static struct EventHandler {} 201 assert(!__traits(compiles, new ComponentFromTag!tag(EventHandler())), "Did compile Component, but shouldn't have"); 202 }